关于负载均衡
负载均衡一般分为服务端负载均衡和客户端负载均衡:
- 服务端负载均衡:比如Nginx、F5等等,请求到达服务器之后由这些负载均衡器根据一定的算法将请求路由到服务器处理
- 客户端负载均衡:比如我们要讲解的Ribbon,服务消费者客户端会有一个服务器地址列表,调用方在请求前通过一定的负载均衡算法选择一个服务器进行调用,负载均衡算法的执行是在请求客户端进行
Ribbon是Netflix发布的负载均衡器。Eureka一般配合Ribbon使用,Ribbon利用从Eureka中读到的服务信息,在调用服务提供者提供服务时,会根据一定的算法进行负载。
Ribbon高级应用
我们是用Ribbon时不需要额外引入响应的jar包,因为我们在服务消费者中我们引入过eureka-client,它会引入Ribbon相关的jar。
使用时我们只需要在注入RestTemplate
时添加上对应的注解即可:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
修改服务提供者的启动方式,使其支持多窗口启动,我们启动两个实例,端口号分别是9000和9002:
启动之后,我们在服务消费者中添加如下接口去调用服务提供者的相关接口:
@GetMapping("hello")
public String hello() throws InterruptedException {
return restTemplate.getForObject("http://scn-service-resume/resume/hello", String.class);
}
由上述代码我们可以看到,我们在添加了Ribbon之后,RestTemplate的调用方式也发生了变化:我们不用使用具体的服务所在的host而是使用服务提供者的服务名称作为代替。
改造之后,我们发起多次调用,会发现我们的服务消费者会轮询的调用两个服务提供者的相关接口。
Ribbon负载均衡策略
Ribbon内置了多种负载均衡策略,内部负责负载均衡的顶级接口为com.netfliex.loadbalancer.IRule
,类树如下:
负载均衡策略 | 描述 |
RoundRobinRule:轮询策略 | 默认超过10次获取到的server都不可用,会返回一个空的server |
RandomRule:随机策略 | 如果随机到的server为Null或者不可用的话,会while不停的循环选取 |
RetryRule:重试策略 | 一定时限内循环重试。默认继承RoundRobinRule,也支持自定义注入,RetryRule会在每次选取之后,对选举的server进行判断,是否为null,是否alive,并且在500ms内会不停的选取判断。而RoundRobinRule失效的策略是超过10次,RandomRule是没有失效时间的概念,只要serverList没都挂 |
BestAvailableRule:最小连接数策略 | 遍历serverList,选取出可用的且连接数最小的一个server。该算法里面有一个LoadBalancerStats的成员变量,会存储所有的server的运行状况和连接数。如果选取到的server为null,那么会调用RoundRobinRule重新选取 |
AvailabilityFilteringRule:可用过滤策略 | 扩展了轮询策略,会先通过默认的轮询选取一个server,再去判断该server是否超时可用,当前的连接数是否超限,都成功再返回 |
ZoneAvoidanceRule:区域权衡策略(默认策略) | 扩展了轮询策略,继承了2个过滤器:ZoneAvoidancePredicate和AvailabilityPredicate,除了过滤超时和连接数过多的server,还会过滤掉不符合要求的zone区域里面的所有节点,AWS--ZONE在一个区域/机房内的服务实例中轮询 |
修改负载均衡策略的配置示例如下:
# 针对的被调用方微服务名称,不加就是全局生效
scn-service-resume:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
#请求连接超时时间 超时时间为连接时间+请求处理时间 如果配制了ribbon的超时时间和重试 hystrix的超时时间要大于 ribbon的超时时间*重试次数
#ConnectTimeout: 2000
#请求处理超时时间
#ReadTimeout: 5000
#对所有操作都进行重试
OkToRetryOnAllOperations: true
# 根据如上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由MaxAutoRetries配置),
# 如果不行,就换一个实例进行访问,如果还不行,再换一次实例访问(更换次数由MaxAutoRetriesNextServer配置),
# 如果依然不行,返回失败信息。
MaxAutoRetries: 0 #对当前选中实例重试次数,不包括第一次调用
MaxAutoRetriesNextServer: 0 #切换实例的重试次数
如果有兴趣的小伙伴,可以在源码中的探索一下Ribbon的自动装配原理来复习一下SpringBoot的自动装配机制。今天Ribbon相关的只是就到这里了,欢迎小伙伴积极留言交流~~~
文章评论