负载均衡
# 简介
使用了微服务后,一般会有多个服务提供者,为了提高系统的性能和可用性,需要对请求进行负载均衡。负载均衡算法有轮询算法,加权轮询算法,随机算法,加权随机算法,最小活跃数算法,一致性Hash算法。
# 负载均衡算法
- 轮询算法
- 随机算法
- 加权随机算法
# spring-cloud-loadbalancer
spring cloud 提供的客户端负载均衡和实现。
- ReactiveLoadBalancer 响应式编程使用
webClient
- BlockingLoadBalancerClient 传统的请求
RestTemplate
# 目前实现的算法
1. RoundRobinLoadBalancer // 轮询
2. RandomLoadBalancer // 随机
2
# ServiceInstanceListSupplier
spring-cloud-loadbalancer 提供了很多的 **ServiceInstanceListSupplier ** ,对应不同的场景使用。
CachingServiceInstanceListSupplier 缓存实现,如果每次请求都访问一次注册中心那么会很浪费性能。提供了缓存的能力,当放生远程调用时先到缓存里面找,如果能找到要调用的服务,就直接使用。
注意
这里有一个坑,我在做优雅服务停机的时候遇到。当我关闭某个服务,该服务会主动下线,按道理调用方应该能感知到,我看nacos的源码,下线后会立马发送UDP报文通知其他服务,感知下线,但是我再实验的时候,发现下线的服务依然被调用,最后定位到是因为loadbalancer加了缓存,解决方案是起一个监听器,监听到服务下线,就清空缓存。
ZonePreferenceServiceInstanceListSupplier 按区路由,优先调用同一个zone
的服务,如果找不到就返回全部服务,再进入下一步负载均衡策略(随机or轮询)
SameInstancePreferenceServiceInstanceListSupplier 使用同一个服务进行调用
# 程序启动初始化
在LoadBalancerAutoConfiguration
中初始化了LoadBalancerInterceptor,并把LoadBalancerInterceptor加入到restTemplate中restTemplate.setInterceptors(list);
# 执行流程
- restTemplate请求远程服务
- 进入到拦截器LoadBalancerInterceptor
- 拦截器从注册中心获取服务列表
- 根据配置的负载均衡策略选择服务
- 最后把地址的url替换成IP和端口
- 发送HTTP请求。