赞
踩
负载均衡的二种实现
1.1)服务端的负载均衡(Nginx)
①:我们用户服务发送请求首先打到Ng上,然后Ng根据负载均衡算法进行选择一个服务调用,而我们的Ng部署在服务器上的,所以Ng又称为服务端的负载均衡(具体调用哪个服务,由Ng所了算)
1.2)客户端负载均衡(ribbon)
spring cloud ribbon是 基于NetFilix ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试
等。通过Load Balancer(LB)获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法
目的:“就是 根据 微服务名称去注册中心拉取对应IP进行替换”
负载均衡算法:
解释:
①:RandomRule(随机选择一个Server)
②: RetryRule
对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server.
③: RoundRobinRule
轮询选择, 轮询index,选择index对应位置的Server
④:AvailabilityFilteringRule
过滤掉故障实例 在选择并发较小的实例
⑤:BestAvailableRule
过滤掉失效的服务实例,然后顺便找出并发请求最小的服务实例来使用
⑥:WeightedResponseTimeRule (这个类是ribbon自己实现的,基于nacos配置权重 也 实现了一个)
根据 服务提供方服务器响应的时间越短 权重越大,被选中的可能性越高;
⑦:ZoneAvoidanceRule(默认是这个)
判断Server所在Zone(区域的概念)就近原则 和 Server的可用性选择Server,在没有Zone的情况下类是 轮询。
细粒度配置? 基于java代码细粒度配置
RibbonRuleConfig 不能被放在我们主启动类所在包以及子包下,不然就起不到细粒度配置.
推荐: 使用yml的配置方法配置(没有坑)
- stock-service:
- ribbon:
- NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
解决Ribbon 第一次调用耗时高的配置
- ribbon:
- eager‐load:
- enabled: true #会打印出日志:stock-service instantiated a LoadBalancer DynamicServerListLoadBalancer for client stock-service initialized
- clients: stock-service #可以指定多个微服务用逗号分隔
Ribbon一些配置
- # 2个服务之间建立HTTP连接的超时时间
- ribbon.ConnectTimeout=2000
- # 获取/读取stock-service的超时时间
- ribbon.ReadTimeout=5000
- # 对当前实例的重试次数,不包括首次。比如对第一台调用超时了,在调1次。
- ribbon.maxAutoRetries=1
- # 重试服务列表的个数 比如第一台挂了,重试2台
- ribbon.maxAutoRetriesNextServer=2
-
- 也可以为每个Ribbon客户端设置不同的超时时间, 通过服务名称进行指定:
- ribbon-config-demo.ribbon.ConnectTimeout=2000
- ribbon-config-demo.ribbon.ReadTimeout=5000
- http:
- client:
- enabled: true # 开启httpclint, 此时ribbon.ConnectTimeout ,ribbon.ReadTimeout 这两个参数配置才会生效
Ribbon详细配置: Spring Cloud Ribbon配置详解
Ribbon 自定义负载均衡策略
1 基于nacos权重的策略。
我们发现,nacos server上的页面发现 注册的微服务有一个权重的概念。取值为0-1之间
- stock-service:
- ribbon:
- NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #nacos实现的基于权重的负载均衡
2 基于同一个集群优先调用策略
2 基于金丝雀版本权重负载均衡策略(同集群同版本)
(100台) (100台)
order-service stock-service
v1(95) old v1(95) old
v2(5) new v2(5) new
- 演示:
- order-service: 8010 BJ v1
- stock-service: 8011 BJ v1
- stock-service: 8012 BJ v2
- stock-service: 8013 NJ v1
- stock-service: 8014 NJ v2
特殊场景
假如服务启动的时候要使用 restTemplate 去获取别的服务数据的时候,restTemplate 会报错说:找不到 微服务名称
- @Slf4j
- public class AuthIntercept implements HandlerInterceptor,InitializingBean {
- private static final String KEY_URL = "http://stock-service/getKey" ;
- private String securetKey ;
- @Autowired
- private RestTemplate restTemplate;
-
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- log.info("通过密钥校验token:{}",securetKey);
- return true;
- }
-
- // Caused by: java.net.UnknownHostException: stock-service
- @Override
- public void afterPropertiesSet() throws Exception {
- securetKey = restTemplate.postForObject(KEY_URL,null,String.class);
- log.info("获取的Key:{}", securetKey);
- }
- }

restTemplate 在某一个时间点,把LoadBalancerIntercept给设置到属性上
- org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration 这个类
- org.springframework.beans.factory.support.DefaultListableBeanFactory
- preInstantiateSingletons()
- InitializingBean 执行的时机是在getBean()
-
- getBean(){
-
- InitializingBean{
-
- restTemplate(里面没有loaderBalancerIntercept , 所以没办法负载均衡)
-
- }
-
- }
-
- SmartInitializingSingleton
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。