在搭建spring cloud gateway 网关集成sentinel时,查了网上很多资料,发现很多大佬的文章呢,对于熔断和限流异常处理都是统一的,这导致调用网关接口时,有时候就不清楚这个接口是进入了熔断和限流,这里主要介绍对熔断和限流异常进行分开处理。
1、集成pom依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
2、配置文件
spring:
cloud:
# Sentinel控制台连接配置
sentinel:
transport:
# 控制台地址和端口
dashboard: ip:port
# spring.cloud.sentinel.transport.port 这个默认为 8917可不配置,除非你单个服务器上有多个应用要与Sentinel控制台连接
# 服务启动时直接建立心跳连接
eager: true
3、网关限流配置
/**
* 网关限流熔断配置
*/
@Configuration
public class GatewaySentinelConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler() {
return new SentinelFallbackHandler();
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
}
下面这是自定义限流熔断的分开处理,也是本文要介绍的
public class SentinelFallbackHandler implements BlockRequestHandler {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable ex) {
//熔断异常自定义处理
if(ex instanceof DegradeException){
Map result = new HashMap();
result.put("code", 423);
result.put("msg", "接口被熔断了");
return ServerResponse.status(HttpStatus.LOCKED).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromObject(result));
}
//限流等异常自定义处理
Map result = new HashMap();
result.put("code", 429);
result.put("msg", "接口被限流了");
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromObject(result));
}
}
这么写的原因是,我在调试中发现无论触发是限流还是熔断,他的请求都是进入这里,并且触发熔断时,Throwable 类型是 DegradeException;而触发限流的异常是有很多种的,这里就没有进行细分,需要细分的可以自己调试看看。