Ribbon负载均衡策略
在上一章中讲到了 springcloud官方提供的负载均衡器
Ribbon 是一种客户端负载均衡器,原理是通过注册中心拉去服务实例列表,通过ribbon 提供的负载均衡策略选中特定的实例,进行请求
Ribbon默认的负载均衡策略是 轮询, 那么 Ribbon 有哪些负载均衡策略呢
Ribbon 的负载均衡策略
策略类 | 名称 | 备注 |
---|---|---|
RandomRule | 随机 | 随机选择 Server |
RandomRobinRule | 轮询 | 按顺序循环选择server |
RetryRule | 重试 | 在一个配置的时间段内 当选择server 不成功,则一直尝试选择一个可用的 server |
BestAvailableRule | 最低并发策略 | 逐个考察server,如果server 断路器打开则忽略,再选择其中并发连接最低的server |
AvailabilityFilteringRule | 可用过滤策略 | 过滤掉一直连接失败并被标记为 circuit tripped 的server, 过滤掉那些高并发连接的server【active connections 超过配置的阈值】 |
ResponseTimeWeightRule | 响应时间加权策略 | 根据server 的响应时间选择.响应时间越短,权重越高,也容易被选中 |
ZoneAvoidanceRule | 区域权重策略 | 综合判断server 所在区域的性能和server的可用 轮询选择, 并且pan判定一个AWS Zone 的运行性能是否可用,剔除不可以Zone中的所有server |
tips : nginx 的负载策略有 轮询,权重weight,ip_hash等
知道了Ribbon 的默认负载均衡策略,也知道了Ribbon 提供的其他负载均衡策略.那么我们怎么才能够应用呢
全局替换掉默认的负载均衡策略,我们需要一个
全局配置策略-配置类
@Configuration
public class MyConfiguration{
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
就这样简答的配置, 加上之后所有通过Ribbon的请求都会按照配置的规则来进行,七种负载均衡策略想使用哪种,在这里创建出来就行,当然你也可以自定义自己的负载均衡策略,
那么问题来了,如果我不想所有的都按同一种负载均衡策略,咋办
基于注解的局部策略配置
如果我们希望对某一个源服务 设置特有的负载均衡策略,可以通过@RibbonClient
但是值得注意的是
在使用它之前,我们需要对全局配置的代码进行改造
@Configuration
@AvoidScan
public class MyConfiguration{
@Autowired
IclinetConfig config;
public Irule ribbonRule(){
return new RandomRule();
}
}
这里的@AvoidScan
注解是一个空的声明,稍后说明
注入的IclientConfig
是针对客户端的 配置管理器 , 使用@RibbonClient
注解时尤其需要注意它的作用 , 最后我们再启动类上加上 @RibbonClient
注解来对源服务进行负载均衡
@RibbonClient(name="client-a",configuration=MyConfiguration.class)
@componentScan(excludeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION,value={AvoidScan.class})})
关于这个配置,简答说一下
@RibbonClient
配置还是一样的套路,意思对于client-a
服务采用MyCofiguration
配置的策略进行负载均衡
@ComponentScan
中的配置意思是让Spring
不去扫描被@AvoidScan
注解标记的配置类,因为我们的配置是对于单个源服务配置的,不能应用于全局,不排除就会报错
总的来说,很简单,就是全局配置的类用@AvoidScan
标记一下,在启动主类通过@RibbonClient
指定服务和配置,并通过@ComponentScan
将其排除全局扫描
当然如果你不习惯使用注解来配置,你也可以使用
基于配置文件的策略配置
基本语法是
<client name>.ribbon.*
,使用这个可以省略掉任何代码的配置
举个例子 : 对服务client-a 使用随机策略
client-a:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
配置也很简单,指定服务应用的负载均衡类,至于类是哪个,可以去前面的的表中看看↑↑↑
在http请求中,免不了极端环境的失败,那么调用的时限控制和重试就很重要了
Ribbon的超时和重试
基本套路如下
client-a:
ribbon:
ConnectionTimeout: 30000
ReadTimeout: 30000
MaxAutoRetries: 1 #对第一次请求的服务重试次数
MaxAutoRetriesNextServer: 1 # 要重试的下一个服务的最大数量【不包括第一个服务】
MaxAutoRetriesAllOperations: true
Ribbon的饥饿加载
Ribbon
在进行客户端负载均衡时并不是在启动的时候就加载上下文,而是在实际请求的时候才去创建【lazy load
】
这个特征会让我们的第一次请求显得特别疲软乏力,就像有的车,起步太肉了,没劲,严重的时候会造成请求超时
如果出现此类情况可以配置饥饿加载,在启动的时候加载上下文
ribbon:
eager-load:
enabled: true
clients: client-a,client-b,client-c
配置文件一目了然,就不赘述了
说了这么久的官方配置,说好的自定义负载均衡策略呢,官方的我就是不爱用咋办
使用配置文件自定义Ribbon客户端
Ribbon是可以自定义客户端的
原理就是通过配置文件来默认加载一些类【这一点在程序设计中是一个思想,以往大家能举一反三】,从而更改ribbon客户端的行为方式,并且使用这种方式的优先级最高,优先级高过使用@RibbonClient注解的配置和源码加载的相关Bean
以下给出语法说明
配置项 | 备注 |
---|---|
<clientName>.ribbon.NFLoadBalancerClassName | 指定 ILoadBalancer 的实现类 |
<clientName>.ribbon.NFloadBalancerRuleClassName | 指定IRule 的实现类 |
<clientName>.ribbon.NFLoadBalancerPingClassName | 指定IPing 的实现类 |
<clientName>.ribbon.NIWSServerListClassName | 指定ServerList 的实现类 |
<clientName>.ribbon.NIWSServerListFilterClassName | 指定ServerListFilter 的实现类 |
然后给出一个配置示范:
client:
ribbon:
NIWSServerListClassName: com.netflix.loadBalancer.ConfigurationBasedServerList
NFLoadBalancerRuleClassName: com.netflixloadbalancer.WeightedResponseTimeRule
Ribbon 脱离Eureka 的使用
一般来说,ribbon都是结合注册中心来使用的,因为需要Ribbon从注册中心拉取实例列表,来选择实例进行负载均衡
但是有一种情况是不适合这样做的,比如一个供很多人使用的公共注册中心,比如社区服务Eureka http://eureka.springcloud.cn
,这就很容易产生服务入侵,所以就不要从Eureka 中读取服务列表,而是应该在Ribbon客户端指定源服务地址,让Ribbon脱离Eureka来使用
首先,我们需要在ribbon禁用eureka功能
ribbon:
eureka:
enabled: false
然后设置源服务列表
client:
ribbon:
listOfServers: http://localhost:8080,http://localhost:8081,http://localhost:8082
配置简单,不再赘述
总结
很简单的一章
1 ribbon的负载均衡策略,全局配置,指定服务配置,配置文件配置,
2 ribbon 的饥饿加载解决 第一次请求超时的问题
3 ribbon 自定义客户端
4 ribbon 脱离Eureka的使用,防止服务入侵