Retry
实例
spring:
cloud:
gateway:
routes:
- id: organization-service
uri: lb://organization-service
predicates:
- Path=/org/**
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
上面的重试过滤器,有5个配置:
- retries:默认为3,用来标识重试次数
- series:用来指定哪些段的状态码需要重试,默认
SERVER_ERROR
,即5xx。 - statuses:用于指定哪些状态需要重试,默认为空,它跟
series
至少得指定一个。一般不怎么配置这个。 - methods:于指定那些方法的请求需要重试,默认为
GET
- exceptions:用于指定哪些异常需要重试,默认为
java.io.IOException
、java.util.concurrent.TimeoutException
除了retries
、exceptions
,其他3项的对应的枚举类为:
- series:org.springframework.http.HttpStatus.Series
- statuses:org.springframework.http.HttpStatus
- methods:org.springframework.http.HttpMethod
重试过滤器源码位置: org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory
、org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory.RetryConfig
Fallback
首先必须确保加入如下依赖:
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
实例:
spring:
cloud:
gateway:
routes:
- id: organization-service
uri: lb://organization-service
predicates:
- Path=/org/**
filters:
- name: Hystrix
args:
name: fallback
fallbackUri: 'forward:/fallback'
上面配置包含了一个 Hystrix
过滤器,该过滤器会应用Hystrix
熔断与降级,会将请求包装成名为fallback
的路由指令RouteHystrixCommand
,RouteHystrixCommand
继承于HystrixObservableCommand
,其内包含了Hystrix
的断路、资源隔离、降级等诸多断路器核心功能,当网关转发的请求出现问题时,网关能对其进行快速失败,执行特定的失败逻辑,保护网关安全。
配置中有一个可选参数fallbackUri
,当前只支持forward
模式的URI
。如果服务被降级,请求会被转发到该URI
对应的控制器。控制器可以是自定义的fallback
接口;也可以使自定义的Handler
,需要实现接口org.springframework.web.reactive.function.server.HandlerFunction
。
定义 fallback 接口
Spring Cloud Gateway
支持自定义fallback
接口。在gateway
模块定义fallback
接口,示例如下:
@ResponseBody
@RequestMapping("/fallback")
public Object fallback() {
// return something
}
定义 fallback 处理器
@Slf4j
@Component
public class HystrixFallbackHandler implements HandlerFunction {
private ErrorResponse ERROR_RESPONSE = new ErrorResponse();
@PostConstruct
private void init() {
ERROR_RESPONSE.setCode(9999);
ERROR_RESPONSE.setMessage("服务异常");
}
@Override
public Mono handle(ServerRequest serverRequest) {
serverRequest.attribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR)
.ifPresent(originalUrls -> log.error("网关执行请求:{}失败,hystrix服务降级处理", originalUrls));
return ServerResponse
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(ERROR_RESPONSE));
}
}
说明:
- ErrorResponse:封装了
code
和message
的统一错误返回对象。 - ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR:网关在转发请求之前,会把一些关键属性放到请求体的
attribute
中,通过GATEWAY_ORIGINAL_REQUEST_URL_ATTR
可以获取原请求URL
。如果通过RequestContextHolder
的方式获取,那么获取到的其实是服务降级后 forward 请求,这里为/fallback
。
配置 fallback 处理器
@Configuration
public class RouterFunctionConfiguration {
@Autowired
private HystrixFallbackHandler hystrixFallbackHandler;
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route(
RequestPredicates.GET("/fallback")
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler);
}
}
注意
当同时配置了重试过滤器和降级过滤器,降级过滤器需要配在重试过滤器之前:
spring:
cloud:
gateway:
routes:
- id: organization-service
uri: lb://organization-service
predicates:
- Path=/org/**
filters:
- name: Hystrix
args:
name: fallback
fallbackUri: 'forward:/fallback'
- name: Retry
args:
retries: 3
series:
- SERVER_ERROR
methods:
- GET
可以看下Spring Cloud
的开发成员怎么说的:Put hystrix before retry
推荐阅读
Spring Cloud 进阶玩法