spring cloud gateway
RetryGatewayFilter 是 Spring Cloud Gateway 对请求重试提供的一个 GatewayFilter Factory。配置方式如下所示。
spring:
cloud:
gateway:
routes:
- id: zuul-encrypt-service
uri: lb://zuul-encrypt-service
predicates:
- Path=/data/**
filters:
- name: Retry
args:
retries: 3
series: SERVER_ERROR
上述代码中具体参数含义如下所示。
retries:重试次数,默认值是 3 次。
series:状态码配置(分段),符合某段状态码才会进行重试逻辑,默认值是 SERVER_ERROR,值是 5,也就是 5XX(5 开头的状态码),共有 5 个值,代码如下所示。
public enum Series {
INFORMATIONAL(1), SUCCESSFUL(2), REDIRECTION(3), CLIENT_ERROR(4), SERVER_ERROR(5);
}
上述代码中具体参数含义如下所示。
statuses:状态码配置,和 series 不同的是这里是具体状态码的配置,取值请参考 org.springframework.http.HttpStatus。
methods:指定哪些方法的请求需要进行重试逻辑,默认值是 GET 方法,取值代码如下所示。
public enum HttpMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
上述代码中具体参数含义如下所示。 exceptions:指定哪些异常需要进行重试逻辑。默认值是 java.io.IOException 和 org.springframework.cloud.gateway.support.TimeoutException。
ribbon
ribbon实现了负载均衡,如果访问某服务的A节点超时后,会触发ribbon的重试机制
全局设置:
ribbon:
ReadTimeout: 6000
ConnectTimeout: 6000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 2
局部设置:
service-id:
ribbon:
ReadTimeout: 6000
ConnectTimeout: 6000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 2
ribbon.MaxAutoRetries 设置为1,请求某服务6s超时后准备重试,该重试策略会先尝试再访问该实例,如果失败1次之后才更换实例访问。
ribbon.MaxAutoRetriesNextServer 决定了尝试更换2次实例。
幂等问题
重试的接口,必然伴随着幂等问题。
解决办法:
方案一:
基于数据库的主键或者唯一索引,避免重复存库
方案二:
基于Redis实现。利用id或者订单号等其他唯一的号码,存于Redis,执行接口代码之前先判断是否有该key,如果有证明已经执行过该接口,后续请求直接拒绝。