Ribbon 实现了 Spring Cloud 定义的客户端负载均衡模块,当消费端(Consumer)访问提供端(Provider)的服务节点超时或不可用时,可以触发 Ribbon 的重试机制。
相关依赖包
通过 starter 形式,导入 ribbon 相关的 jar 包,具体如下:
maven 项目:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
gradle 项目:
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-ribbon'
此外,还要导入 spring 的重试相关包,具体如下:
maven 的 pom.xml 添加如下依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
基于 gradle 的项目在 build.gradle 里如下添加:
compile group: 'org.springframework.retry', name: 'spring-retry'
重试配置
在 application.yml 里增加重试启用的配置及具体重试配置:
spring:
cloud:
loadbalancer:
retry:
enabled: true
如上配置开启负载均衡的重试。
如果想要针对所有被当前服务调用的所有其他服务进行统一的重试配置,可以如下配置。
全局配置:
ribbon:
# 连接超时
ConnectTimeout: 20000
# Socket 读取超时
ReadTimeout: 500
# 同一实例最大重试次数,不包括首次调用
MaxAutoRetries: 1
# 重试的其他实例的个数,不包括首次调用的 server
MaxAutoRetriesNextServer: 2
# 是否所有操作都进行重试(和接口的幂等性有关)
OkToRetryOnAllOperations: false
也可以针对指定服务(service)进行特定重试配置:
局部配置:
service-id:
ribbon:
ConnectTimeout: 20000
ReadTimeout: 500
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 2
OkToRetryOnAllOperations: false
其中 service-id 是 Spring Cloud 中指定的服务名称,如 @FeignClient
中指定的调用服务名称。
重试配置项详解
Ribbon 常用的重试配置项主要有如下几个:
- ConnectTimeout
- TCP 连接的超时阈值。
- ReadTimeout
- Socket 读取的超时阈值。
- MaxAutoRetries
- 同一个实例最大重试次数,不包括首次调用。
- MaxAutoRetriesNextServer
- 重试的其他实例的个数,不包括首次调用的 server 实例。
- OkToRetryOnAllOperations
- 是否所有操作都进行重试。
从上面的配置项描述可知,一个请求理论上在一个实例的最大请求数为 ( MaxAutoRetries + 1 ),请求的最大实例数为 ( MaxAutoRetriesNextServer + 1 )。
所以,一个 request 理论上的最大请求数为 ( MaxAutoRetries + 1 ) * ( MaxAutoRetriesNextServer + 1 ),如上配置就是 ( 1 + 1 ) * ( 2 + 1 ) = 6,即 6 次。
OkToRetryOnAllOperations 配置项针对重试的适用范围,在启用重试时,一定要考虑被调用服务接口的幂等性,对该参数的设置可以总结为如下 2 点:
- 如果 api 没有完全考虑幂等性,建议不要把 OkToRetryOnAllOperations 设置为 true;
- 其次,如果即使设置为 false,如果被调用服务接口为 Get 方式的涉及资源操作,无法满足幂等性,也不建议启用重试机制。