启用负债均衡
- 在RestTemplate的
**bean**上添加**@LoadBalanced**注解即可自动负债均衡- 使用了
**LoadBanlanced**后,RestTeemplate的url里不能再出现**ip:port**必须使用服务名替代 - 负债均衡是对主调方才需要,被调方不需要设置负载均衡
- 使用了
Spring Cloud Ribbon 不像注册中心、配置中心、网关那样独立部署、运行。它更像是一个工具类(库),“嵌套” 在各个组件中配合其它组件使用
@Bean@LoadBalancedRestTemplate restTemplate() {return new RestTemplate();}
配置
注意服务名貌似必须是
**xxx-service**的形式 ```propertiesxxx-service是服务名,注意服务名必须是xxx-service的形式
xxx-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
启用饥饿加载
ribbon.eager-load.enabled=true
指定要进行饥饿加载的服务
ribbon.eager-load.clients=aservice-sms,xxx,xxx
ribbon.restclient.enabled=true #启用超时重试 ribbon.ReadTimeout=1000 #超时时间设置 ribbon.MaxAutoRetries=2 #一个实例的最大重试次数 ribbon.MaxAutoRetriesNextServer=2 #重试下一个实例的最大次数
除了上面那种对所有服务都生效的配置,还可以针对具体某个服务进行配置
xxx-service.ribbon.readTimeout=3000 xxx-service.ribbon.MaxAutoRetries=2 xxx-service.ribbon.MaxAutoRetriesNextServer=0 ```
@LoadBalanced的原理
- 原因 1项目间接引用到了 Ribbon ,spring-cloud-starter-alibaba-nacos-discovery 包中已经包含了 ribbon 。当然,你也可以单独引用(spring-cloud-starter-netflix-eureka-ribbon),不过,逻辑上这就是一句啰嗦的废话;
- 原因 2:你的项目是一个 Nacos Client 项目,当它启动时,它会去 Nacos Server 上拉取已注册的所有的服务的 IP 地址等相关信息;
- 原因 3:当你通过 RestTemplate 以 application-name 为依据发出请求时,Ribbon 会参与进来,会将 application-name “替换” 成上述第 2 步中查到的 IP 地址。
- 原因 4:在 “替换” 的过程中,它以某种规则轮流使用同一个服务的多个实例的 IP 地址,从而实现负载均衡效果。这里的 “某种规则” 指的就是负载策略。
- 原因 5:默认的负载策略是轮循。
Ribbon的执行过程
- ribbon以拦截器的方式参与到RestTemplate的请求发送中去,拦截器的执行步骤如下:
**RestTemplate**默认没有任何拦截器。
- 第 1 步: 获取服务名
- 拦截器通过 request.getURI() 方法获得当前 RestTemplate 所要发出的请求的 URI ,此时 URI 中的内容是目标服务的 application-name 而非 IP 。
- 第 2 步:获取服务 IP 和端口
- 由于我们的项目作为 Nacos Client 能够从 Nacos Server 上拉取到服务名 所对应的一个(或多个)IP 地址及端口信息,因此,Ribbon 会根据某种 “规则” 获取到目标服务的真实的访问路径。
- 注册中心和配置中心的一个作用体现出来了:只要服务名不变,修改服务的域名,端口等不需要再改变太多的调用者
第 3 步:替换服务名
Ribbon内置 了8种负载均衡策略(其实是7种)。这些策略都直接或者间接实现了
**IRule**接口。常见的如下:RandomRule:随机策略,随机选择目标服务的实例RoundRobinRule轮询策略,默认的负债均衡策略。按照顺序选择实例WeightedResponseTimeRule根据响应时间分配一个 Weight(权重),响应时间越长,Weight 越小,被选中的可能性越低。- 这个策略老版本的名称为
ResponseTimeWeightedRule
- 这个策略老版本的名称为
BestAvailablRule这种策略下,Ribbon 会观测、统计目标服务的各个实例的并发量。当再次发起对目标服务的访问时,Ribbon 会先过滤掉因为多次访问故障而被标记为 Error 的 实例。然后选择一个并发量(ActiveRequestCount)最小的实例发起访问。- 俗话说就是:先去掉不能干活的,然后在能干活的里面找一个最闲的。
除了上面4种常用的,还有如下2种,下面2种需要结合结合断路、超时等参数配置,使用起来比较复杂,容易进坑,所以使用较少。
默认情况下,服务消费方调用服务提供方接口的时候,第一次请求会慢一些,甚至会超时,而之后的调用就没有问题了。
- 这是因为 Ribbon 进行客户端负载均衡的 Client 并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的 Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建 RibbonClient 的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易就会出现上面所描述的现象。
可以启用
**Ribbon**的饥饿加载,即立即加载。并指定在项目启动时就要加载的服务超时与超时重试
Ribbon 是有超时设置,以及超时之后的重试功能的。早年,Ribbon 的超时设置和重试设置的配置方式一直在变动,因此有很多『配置无效』的现象,十分诡异。
- Ribbon 的超时重试总次数是
(1 + MaxAutoRetries ) x (1 + MaxAutoRetriesNextServer)- 注意重试次数不包含本身请求那一次
