启用负债均衡

  • 在RestTemplate的**bean**上添加**@LoadBalanced**注解即可自动负债均衡
    • 使用了**LoadBanlanced**后,RestTeemplate的url里不能再出现**ip:port** 必须使用服务名替代
    • 负债均衡是对主调方才需要,被调方不需要设置负载均衡
  • Spring Cloud Ribbon 不像注册中心、配置中心、网关那样独立部署、运行。它更像是一个工具类(库),“嵌套” 在各个组件中配合其它组件使用

    1. @Bean
    2. @LoadBalanced
    3. RestTemplate restTemplate() {
    4. return new RestTemplate();
    5. }

    配置

  • 注意服务名貌似必须是**xxx-service**的形式 ```properties

    xxx-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 的返回(一个真实可用的 ip:port )后,会用它替换掉当前请求的 URI 中的服务名,然后放行请求,向目标服务继续发起 HTTP 请求(并获取返回)。

      负载均衡策略和 IRule 接口

  • Ribbon内置 了8种负载均衡策略(其实是7种)。这些策略都直接或者间接实现了**IRule**接口。常见的如下:

    • RandomRule:随机策略,随机选择目标服务的实例
    • RoundRobinRule 轮询策略,默认的负债均衡策略。按照顺序选择实例
    • WeightedResponseTimeRule 根据响应时间分配一个 Weight(权重),响应时间越长,Weight 越小,被选中的可能性越低。
      • 这个策略老版本的名称为ResponseTimeWeightedRule
    • BestAvailablRule 这种策略下,Ribbon 会观测、统计目标服务的各个实例的并发量。当再次发起对目标服务的访问时,Ribbon 会先过滤掉因为多次访问故障而被标记为 Error 的 实例。然后选择一个并发量(ActiveRequestCount)最小的实例发起访问。
      • 俗话说就是:先去掉不能干活的,然后在能干活的里面找一个最闲的。
  • 除了上面4种常用的,还有如下2种,下面2种需要结合结合断路、超时等参数配置,使用起来比较复杂,容易进坑,所以使用较少。

    • AvailabilityFilteringRule
    • ZoneAvoidanceRule

      饥饿加载

  • 默认情况下,服务消费方调用服务提供方接口的时候,第一次请求会慢一些,甚至会超时,而之后的调用就没有问题了。

  • 这是因为 Ribbon 进行客户端负载均衡的 Client 并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的 Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建 RibbonClient 的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易就会出现上面所描述的现象。
  • 可以启用**Ribbon**的饥饿加载,即立即加载。并指定在项目启动时就要加载的服务

    超时与超时重试

  • Ribbon 是有超时设置,以及超时之后的重试功能的。早年,Ribbon 的超时设置和重试设置的配置方式一直在变动,因此有很多『配置无效』的现象,十分诡异。

  • Ribbon 的超时重试总次数是(1 + MaxAutoRetries ) x (1 + MaxAutoRetriesNextServer)
    • 注意重试次数不包含本身请求那一次