• 问题:
    在zuul中想要开启客户端负载均衡的重试机制,网上有很多文章介绍,但是我尝试一下他们提供的配置,发现不起作用。后来通过仔细查找网上别人的文章,最终成功开启重试,记录下来,希望可以帮到别人少做弯路。
  • 环境:
  1. Spring Cloud: Hoxton.SR7
  2. Spring boot: 2.3.3.RELEASE
  • 解决方法:
  1. 在pom.xml文件中引入 spring-retry包。这是zuul重试机制必须依赖的一个包,但很多文章没有提及。
<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
  1. 配置zuul的application.yml
zuul:
  ##注意,这里必须开启
  #开启重试,
  retryable: true
  #使用线程池做隔离,默认是信号量SEMAPHORE(信号量)
  ribbon-isolation-strategy: thread
  thread-pool:
    #为不同的路由使用不同的线程池
    use-separate-thread-pools: true
    #线程名称前缀
    thread-pool-key-prefix: zuulgw

##针对服务实例的超时和重试策略
hello-world: #服务实例的名称,也有是服务里的yml文件中spring.applicaiton.name的设置。
  ribbon:
    #ribbon请求连接的超时时间
    ConnectTimeout: 1000
    #请求处理的超时时间
    ReadTimeout: 1000
    #对所有请求操作都进行重试。设置为false,表示只会对get请求进行重试
    OkToRetryOnAllOperations: true
    #对服务实例的重试次数(除去首次访问外)。默认值为0,如果不设置,则只会有首次访问,不会有重试
    MaxAutoRetries: 1
    #切换到另一个实例的次数。默认值为1,如果不设置,会有一次切换
    MaxAutoRetriesNextServer: 1
 
##全局超时和重试策略
ribbon:
  #建立连接的超时时间
  ConnectTimeout: 1000
  #请求处理的超时时间
  ReadTimeout: 1000
  #对所有请求操作都进行重试。设置为false,表示只会对get请求进行重试
  OkToRetryOnAllOperations: true
  #对服务实例的重试次数(除去首次访问外)。如果不设置,则只会有首次访问,不会有重试
  MaxAutoRetries: 1
  #切换到另一个实例的次数。如果不设置,会有一次切换
  MaxAutoRetriesNextServer: 1

hystrix:
  command:
    default:
      execution:
        #启用超时时间
        timeout:
          enabled: true
        isolation:
          thread:
            #Hystrix断路器的超时时间,设置时间需要超过上面ribbon的连接过期时间,加上重试的时间
            timeoutInMilliseconds: 8500
  1. 几点提醒:
    a. 想要开启重试机制,必须引入spring-retry包和配置applicaiton.yml中的zuul.retryable=true,两者缺一不可。
    b. 注意application.yml中的两个配置:
    - MaxAutoRetries: 表示对服务实例的重试次数(除去首次访问外)。默认为0,表示只会有首次访问,不会有重试
    - MaxAutoRetriesNextServer:切换到另一个另一个实例的次数。默认为1,表示会有一次切换
    比如设置:MaxAutoRetries=1MaxAutoRetriesNextServer=1, 则表示先对第一个服务实例发起请求(请求1),超时后重试(请求2),再超时,会换一个服务实例,再发起一个请求(请求3),如果超时,会再重试一次(请求4),这样对两个服务实例,总共发起了4次请求。
    c. 注意hystrix.command.default.execution.isolation.thread.timeoutInMillisecondshystrix超时的设置。这个值不能设置过小,否则会发生hystrix timeout熔断,fallback信息返回,但是zuul的重试仍然正在进行中。这个值得设置有一个公式,如下。
    hystrix.timeoutInMilliseconds >= ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1)d. 另外,如果不引入spring-retry包,也能开启重试机制,需要在applicatin.yml中设置ribbon.restclient.enabled=truezuul.retryable=true仍然需要设置)。它会使用ribbon中的RestClient去替代zuul中的HttpClient去实现http连接。但是,按照官方文档的说法,它有一个缺陷,不支持HTTP的PATCH方法请求。所以不推荐这么设置。