Spring Cloud Gateway集成Sentinel流控详情
概述
Sentinel 支持对 spring cloud Gateway、Zuul 等主流的 api Gateway 进行限流。
Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑:
GatewayFlowRule
:网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。ApiDefinition
:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫my_api
,请求 path 模式为/foo @Configuration public class GatewayConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; } @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { // ReGISter the block exception handler for spring Cloud Gateway. return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } @Bean @Order(-1) public GlobalFilter sentinelGatewayFilter() { return new SentinelGatewayFilter(); } @PostConstruct public void doInit() { initCustomizedApis(); } private void initCustomizedApis() { BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { @Override public Mono<ServerResponse> handleRequest(ServerWEBExchange serverWebExchange, Throwable throwable) { // 自定义异常处理 HashMap<String, String> map = new HashMap<>(); map.put("code", "10099"); map.put("message", "服务器忙,请稍后再试!"); return ServerResponse.status(httpstatus.NOT_ACCEPTABLE) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(map)); } }; GatewayCallbackManager.setBlockHandler(blockRequestHandler); } }
除此之外,用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组,然后Sentinel会针对这个分组进行限流,
示例如下:
@PostConstruct
public void doInit() {
initCustomizedApis();
}
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("some_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/ahas"));
add(new ApiPathPredicateItem().setPattern("/product/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("another_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
注意:
- Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。若通过 Spring Cloud Alibaba 接入,请将
spring.cloud.sentinel.filter.enabled
配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。- 若使用 Spring Cloud Alibaba Sentinel 数据源模块,需要注意网关流控规则数据源类型是
gw-flow
,若将网关流控规则数据源指定为 flow 则不生效。
编写配置文件
在bootstrap.yaml
中编写对应的配置
spring:
application:
name: gateway-service
cloud:
loadbalancer:
Nacos:
enabled: true
nacos:
discovery:
server-addr: 192.168.199.128:8848 #Nacos地址
config:
server-addr: 192.168.199.128:8848 #Nacos地址
file-extension: yaml #这里我们获取的yaml格式的配置
gateway:
discovery:
locator:
enabled: true
sentinel:
filter:
enabled: false
transport:
#配置 Sentinel dashboard 地址
dashboard: 192.168.199.128:8858
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
在Nacos中对应的远程配置文件:
spring:
cloud:
gateway:
# 全局的过滤器,跨域配置
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
globalcors:
cors-configurations:
'[/**]':
allowedHeaders: '*'
allowedMethods: '*'
allowedOrigins: '*'
# 路由
routes:
- id: user_servcie_get
uri: lb://user-service
predicates:
- Path=/user/get/{id}
- id: user_service_test
uri: lb://user-service
predicates:
- Path=/user/test
测试
先启动userservice和网关,然后访问一次对应的接口,观察Sentinel控制台
我们给user_service_test添加对应的流控规则:
然后再来访问测试:
如图所示,流控生效
到此这篇关于Spring Cloud Gateway集成Sentinel流控详情的文章就介绍到这了,更多相关Spring Cloud Gateway集成Sentinel 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!