学习spring cloud记录5-Ribbon负载均衡
前言
在上次记录中,后台调用的http://demo-user/demouser/user/test并不是一个直接可用的地址,Ribbon将其拦截拉取eureka的服务列表,然后选择其中一个地址进行请求。
负载均衡流程
当接口调用通过@LoadBalanced注解是,会进入RibbonLoadBalancerClient,向DynamicServerListLoadBalancer传服务的id(服务名),然后从eureka注册中心拉取服务列表,DynamicServerListLoadBalancer获取服务列表后通过IRule的策略选择一条返回给RibbonLoadBalancerClient,然后修改最初的url为ip和port的形式进行请求提供方。
负载均衡策略
内置负载均衡 | 规则描述 |
RoundRobinRule | 简单轮询服务列表。他是Ribbon默认的负载均衡规则。 |
AvailabilityFilteringRule |
对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,着他服务器就会被设置为“短路”状态。短路状态将持续30s,如果再次连接失败,短路的持续时间就会几何级的增加. (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了此规则将会被忽略。并发连接数上限,可以由客户端的<clientName><cllientConfigNameSpace>ActiveConnetionsLimit属性进行配置。 |
WeightedResponseTimeRule | 为每一个服务器授予一个权重值。服务器的响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
ZoneAvoidanceRule(默认) | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房,一个机架等,然后对Zone里面的呢多个服务进行轮询 |
BestAvailableRule | 忽略那些短路的服务器,并选择并发数低的服务器。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 重试机制的选择逻辑。 |
调整负载均衡的规则
代码实现
在代码中定义新的IRule,过程中发现IRule引入失败,需要在pom中添加以下依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.netflix.ribbon/ribbon --> <dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon</artifactId> <version>2.7.18</version> </dependency>
如果将默认策略设置为随机策略,则在启动类中完成以下代码:
@Bean public IRule randomRule(){ return new RandomRule(); }
这种方案作用于全局
配置文件实现
在application中配置如下:
demo-user: #服务名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #策略
然后将启动类的代码注释,重启order服务,当调用接口是报错java.lang.NoSuchMethodError,因为之前IRule没有引入成功,所以在pom中另外引用了ribbon依赖,所以现在在匹配配置文件时出现冲突,此时代码不需要此依赖,将上方的依赖删除即可成功。
这种方案作用域单独的服务。
饥饿加载
Ribbon默认采用懒加载,即第一次访问时创建LoadBalanceClient,请求时间过长。
饥饿加载会在项目启动时创建,降低第一次访问的耗时,通过以下配置开启饥饿加载:
ribbon:
eager-load:
enabled: true
clients:
- demo-user
结语
配置可能不生效,因为依赖引不进来
和springboot以及cloud版本有关,可以试试这对版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.9.RELEASE</version> <relativePath/> </parent> ... <!-- springCloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR10</version> <type>pom</type> <scope>import</scope> </dependency>