Ribbon负载均衡

发布于:2025-07-21 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

一、负载均衡实现逻辑

二、负载均衡策略

三、修改负载均衡规则

 四、饥饿加载


注:Ribbon拦截Eureka请求,找eureka-server拿对应服务信息,根据对应策略返回调用的ip和端口。

一、负载均衡实现逻辑

1、逻辑图

2、ClientHttpRequestInterceptor接口:客户端http请求拦截

3、LoadBalancerInterceptor类实现上面接口 

//该方法拦截http请求
@Override
public ClientHttpResponse intercept(final HttpRequest request,final byte[] body,final ClientHttpRequestExecution execution){
	//得到请求地址:http://user-service/user/1
	final URI originalUri = request.getURI();

	//得到服务名user-service
	String serciceName=originalUri.getHost();
	
	//RibbonLoadBalancerClient loadBalancer 进入负载均衡客户端
	return this.loadBalancer.execute(serviceName,this.requestFactory.createRequest(request,body,execution));
}

4、RibbonLoadBalancerClient类

public <T> T execute(String serviceId,LoadBalancerRequest<T> request,Object hint) throws IOException{
	//根据服务名拿到服务信息 DynamicServerListLoadBalancer 动态服务列表负载均衡器
	ILoadBalancer loadBalancer=getLoadBalancer(serviceId);
	
	//根据指定策略获取具体服务IP端口
	Server server=getServer(loadBalancer,hint);
	if(server==null){
	  throw new IllegalStateException("No instances available for"+serviceId);
	}
    RibbonServer ribbonServer=new RibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId).getMetadata(server));
    return execute(serviceId,ribbonServer,request);
}


protected Server getServer(ILoadBalancer loadBalancer,Object hint){
	if(loadBalancer==null){
		return null;
	}
	return loadBalancer.chooseServer(hint!=null?hint:"default");
}

5、ZoneAwareLoadBalancer类

@Override
public Server chooseServer(Object key){
	if(!ENABLED.get()||getLoadBalancerStats().getAvailableZones().size()<=1){
		logger.debug("Zone aware logic disabled or there is only one zone");
		return super.chooseServer(key);
	}

	Server server=null;
	try{
		LoadBalancerStats lbStats=getLoadBalancerStats();
		
	}
}

 6、BaseLoadBalancer类

public Server chooseServer(Object key){
	if(counter==null){
		counter=createCounter();
	}
	counter.increment();
	if(rule==null){
		return null;
	}else{
		try{
			//调用IRule规则的实现类得到ip端口
			return rule.choose(key);
		}catch(Exception e){
			logger.warn("LoadBalancer [{}]: Error choosing server for key {}",name,key,e);
			return null;
		}
	}
}
二、负载均衡策略
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个接口都是一种规则。

1、IRule层级(Eureka的实现类)

- AbstractLoadBalancerRule:策略抽象类
	1. RetryRule:重试,重试机制的选择逻辑。
	2. ClientConfigEnabledRoundRobinRule:
		-  BestAvailableRule:最低并发,忽略哪些短路的服务器,并选择并发数较低的服务器。		
		- PredicateBasedRule:
			- AvailabilityFilteringRule:可用过滤,[[#AvailabilityFilteringRule作用]]
			- ZoneAvoidanceRule:区域权重,[[#ZoneAvoidanceRule作用]]
	3. RoundRobinRule:轮询,简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
		- WeightedResponseTimeRule:[[#WeightedResponseTimeRule作用]]
	4. RandomRule:随机,随机选择一个可用的服务器。

2、AvailabilityFilteringRule作用

对以下两种服务器进行忽略:

  • 在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为"短路"状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。

  • 并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。

3、ZoneAvoidanceRule作用

  • 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房,一个机架等。而后再对Zone内的多个服务做轮询。 

4、WeightedResponseTimeRule作用

  • 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。

三、修改负载均衡规则

1、引入依赖包

//eureka-ribbon 负载均衡  
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon:2.2.10.RELEASE'

2、代码方式:在order-service中的OrderApplication类中,定义一个新的IRule

@Bean  
public IRule randomRule() {  
	return new RandomRule();  
}

3、 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则

user-service:  
	ribbon:  
		# eureka负载均衡规则  
		NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
		
		# nacos负载均衡规则  
		# NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

4、nacos的ribbon策略实现类

四、饥饿加载
  • Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时。

  • 开启饥饿加载

ribbon:  
	eager-load:  
		# 开启饥饿加载  
		enabled: true  
		clients:  
			# 指定饥饿加载的服务名称  
			- user-service


网站公告

今日签到

点亮在社区的每一天
去签到