2.6 gateway整合sentinel流控降级
网关作为内部系统外的一层屏障, 对内起到一定的保护作用, 限流便是其中之一. 网关层的限流可以简单地针对不同路由进行限流, 也可针对业务的接口进行限流,或者根据接口的特征分组限流。
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81
- 添加依赖
```java
com.alibaba.cloud spring-cloud-alibaba-sentinel-gateway
**2.添加配置**
```java
sentinel:
transport:
# 添加sentinel的控制台地址
dashboard: 127.0.0.1:8080
2.6.1 控制台实现方式:
Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
- route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
- 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
自定义异常方式:
1.通过yml
spring:cloud.sentinel.scg.fallback.mode = response
spring.cloud.sentinel.scg.fallback.response-body = '{"code":403,"mes":"限流了"}'
2.通过GatewayCallbackManager
@Configuration
public class GatewayConfig {
@PostConstruct
public void init(){
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue("降级了!"));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
2.6.1 代码实现方式:(了解)
用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则
GatewayConfiguration中添加
@PostConstruct
public void doInit() {
//初始化网关限流规则
initGatewayRules();
//自定义限流异常处理器
initBlockRequestHandler();
}
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
//resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
//count:限流阈值
//intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
rules.add(new GatewayFlowRule("order_route")
.setCount(2)
.setIntervalSec(1)
);
rules.add(new GatewayFlowRule("user_service_api")
.setCount(2)
.setIntervalSec(1)
);
// 加载网关规则
GatewayRuleManager.loadRules(rules);
}
private void initBlockRequestHandler() {
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
HashMap<String, String> result = new HashMap<>();
result.put("code",String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
result.put("msg", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(result));
}
};
//设置自定义异常处理器
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}