Ribbon负载均衡

目录

一、负载均衡实现逻辑

二、负载均衡策略

三、修改负载均衡规则

四、饥饿加载


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

一、负载均衡实现逻辑

1、逻辑图

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

3、LoadBalancerInterceptor类实现上面接口

java 复制代码
//该方法拦截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类

java 复制代码
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类

java 复制代码
@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类

java 复制代码
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;
		}
	}
}
二、负载均衡策略
java 复制代码
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个接口都是一种规则。

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

java 复制代码
- 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、引入依赖包

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

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

java 复制代码
@Bean  
public IRule randomRule() {  
	return new RandomRule();  
}

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

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

4、nacos的ribbon策略实现类

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

  • 开启饥饿加载

Groovy 复制代码
ribbon:  
	eager-load:  
		# 开启饥饿加载  
		enabled: true  
		clients:  
			# 指定饥饿加载的服务名称  
			- user-service
相关推荐
彩旗飘飘12 小时前
手把手教你用 Spring Cloud Alibaba 搭建毕设级微服务架构:从单体到分布式的完整演进实录
spring cloud·微服务
源远流长jerry15 小时前
Linux 本机网络通信机制深度解析:Loopback 设备原理
linux·运维·服务器·网络·tcp/ip·nginx·负载均衡
Jul1en_19 小时前
【SpringCloud】Eureka、Nacos 简单概念笔记
笔记·spring cloud·eureka
Devin~Y19 小时前
大厂Java面试实战:Spring Boot/Cloud、Redis/Kafka、JVM调优与Spring AI RAG(内容社区UGC+AIGC客服场景)
java·jvm·spring boot·redis·spring cloud·kafka·mybatis
文慧的科技江湖20 小时前
零碳园区综合管理平台PRD需求文档 - 慧知开源充电桩平台
spring cloud·微服务·开源·能源·慧知开源光储充管理平台·慧知开源光储充管理系统·零碳园区管理平台
Jul1en_21 小时前
【SpringCloud】OpenFeign 与 Gateway 讲解与部署
spring·spring cloud·gateway
苏渡苇1 天前
万字长文 | Spring Cloud Alibaba组件之Nacos实战及Nacos客户端服务注册源码解析
spring cloud·微服务·nacos·注册中心·配置中心·sca
下次再写1 天前
微服务架构实战:Spring Boot + Spring Cloud 从入门到精通
java·spring boot·spring cloud·微服务架构·服务注册与发现·分布式系统·api网关
布吉岛的石头2 天前
K8s Ingress配置踩坑实录:生产环境500+并发负载均衡最佳实践
容器·kubernetes·负载均衡
ZOE^V12 天前
springcloud笔记
笔记·spring cloud·github