5Gateway 重试 · SpringCloud微服务实战 · 看云
5. Retry GatewayFilter
导航
前面我们在将Feign、Ribbon的时候已经提到过重试机制,就是在我们发送Http 请求的时候希望一次失败后可以再尝试发送一次,因为前几次可能因为网络等不确定原因。Spring Cloud Gateway对请求重试提供的一个GatewayFilter Factory。
本节代码地址
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-gateways/fw-cloud-gateways-gateway
5.1 应用配置
server:
port: 8711
spring:
application:
name: fw-gateways-gateway
profiles:
active: retry_route
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
---
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: lb://fw-cloud-ribbon-server
predicates:
- After=2020-01-08T18:30:11.965+08:00[Asia/Shanghai]
filters:
- name: Retry
args:
retries: 3
series:
- SERVER_ERROR
statuses:
- INTERNAL_SERVER_ERROR
- BAD_GATEWAY
methods:
- GET
exceptions:
- java.io.IOException
- java.util.concurrent.TimeoutException
profiles: retry_route
Spring Cloud Gateway 通过以下参数来控制重试机制: 。
retries:重试次数,默认值是 3 次statuses:HTTP 的状态返回码,取值请参考:org.springframework.http.HttpStatusmethods:指定哪些方法的请求需要进行重试逻辑,默认值是 GET 方法,取值参考:org.springframework.http.HttpMethodseries:一些列的状态码配置,取值参考:org.springframework.http.HttpStatus.Series。符合的某段状态码才会进行重试逻辑,默认值是 SERVER_ERROR,值是 5,也就是 5XX(5 开头的状态码),共有5 个值。exceptions:应重试的引发异常的列表。backoff:为重试配置的指数补偿。重试在的退避间隔后执行firstBackoff * (factor ^ n),其中n为迭代。如果maxBackoff已配置,则应用的最大退避限制为maxBackoff。如果basedOnPreviousValue为true,则使用计算退避prevBackoff * factor。
5.2 源码分析
public static class RetryConfig implements HasRouteId {
private String routeId;
private int retries = 3;
private List<Series> series;
private List<HttpStatus> statuses;
private List<HttpMethod> methods;
private List<Class<? extends Throwable>> exceptions;
private RetryGatewayFilterFactory.BackoffConfig backoff;
public RetryConfig() {
this.series = RetryGatewayFilterFactory.toList(Series.SERVER_ERROR);
this.statuses = new ArrayList();
this.methods = RetryGatewayFilterFactory.toList(HttpMethod.GET);
this.exceptions = RetryGatewayFilterFactory.toList(IOException.class, TimeoutException.class);
}
......
通过分析RetryConfig,我们可以看到重试支持的参数和默认值。
- 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:指定哪些异常需要进行重试逻辑,默认值是IOException、TimeoutException
5.3 fw-cloud-ribbon-server 代码修改
修改user/{id}接口,随机抛出异常,导致接口重试。
int millis = new Random().nextInt(3000);
System.out.println("client线程休眠时间:"+millis);
Thread.sleep(millis);
if(millis>1000){
throw new RuntimeException("error");
}
5.4 应用重启
浏览器或Postman 输入 localhost:8711/user/1
如果延迟时间超过1秒钟,就会抛异常,默认重试3次,3次之后仍然没有成功就会返回异常信息。

