介绍
网关是所有请求的公共入口,因此可以在网关处对请求进行限流,而且限流的方式很多,本章我们来采用 sentinel 组件实现网关限流
Sentinel 支持对 SpringCloud Gateway、Zuul等主流网关进行限流。
Sentinel 提供了 SpringCloud Gateway 的适配模块,Sentinel 提供了两种资源限流方式。
-
route:在 Spring 配置文件中配置的路由条目,资源名对应的 routeld;
-
自定义API:用户可以利用Sentinel提供的API 来自定义API分组。
一、代码示例
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
@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 GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
//配置初始化的限流参数
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("shop-product")//资源名称,对应路由id
.setCount(1)//限流阀值
.setIntervalSec(1)//统计时间窗口,单位是秒,默认是1秒
);
GatewayRuleManager.loadRules(rules);
}
//配置限流异常处理器
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
//自定义限流异常页面
@PostConstruct
public void initBlockHandlers() {
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map map= new HashMap<>();
map.put("code", 0);
map.put("message", "接口被限流了");
return ServerResponse
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(map));
}
} ;
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
-
resource: 资源名称,它可以是网关中定义的路由(route)名称,或者是用户在Sentinel中自定义的API分组名称。这个属性用于指定限流规则使用的具体资源。 -
esourceMode: 资源模型,用于指明限流规则是应用于API Gateway的路由( RESOURCE_MODE_ROUTE_ID
)还是用户在Sentinel中定义的API分组(RESOURCE_MODE_CUSTOM_API_NAME
)。默认值是路由模式。 -
rade: 限流指标维度,与限流规则的grade字段相同,用于指定限流的具体标准或条件。 -
ount : 限流阈值,表示在指定时间窗口内允许通过的最大请求数。 -
ntervalSec: 统计时间窗口,单位是秒,用于计算限流阈值的时间范围。默认值为1秒。 -
ontrolBehavior: 流量整形的控制效果,与限流规则的controlBehavior字段相同,目前支持快速失败(立即拒绝超出阈值的请求)和匀速排队(将超出阈值的请求放入队列中等待)两种模式。默认是快速失败模式。 -
burst: 应对突发请求时,额外允许的请求数目,这可以在一定程度上提高系统的抗突发能力。 -
maxQueueingTimeoutMs: 在匀速排队模式下,如果请求在队列中等待的时间超过了这个值(以毫秒为单位),则会被拒绝。这个属性仅在匀速排队模式下生效。 -
paramItem: 参数限流配置,用于对具有特定参数的请求进行更精细化的限流控制。如果不提供此配置,则将该网关规则视为普通流控规则;如果提供,则会转换为热点规则。其下包含的子字段有: -
parseStrategy: 从请求中提取参数的策略,支持提取来源IP(
PARAM_PARSE_STRATEGY_CLIENT_IP
)、Host(PARAM_PARSE_STRATEGY_HOST
)、任意Header(PARAM_PARSE_STRATEGY_HEADER
)和任意URL参数(PARAM_PARSE_STRATEGY_URL_PARAM
)四种模式。 fieldName: 当提取策略选择Header模式或URL参数模式时,需要指定具体的Header名称或URL参数名称。
-
pattern和matchStrategy: 这两个字段为后续可能实现的参数匹配特性预留,当前尚未实现。
测试:
在一秒钟内多次访问
就可以看到限流规则起作用了
2.自定义API分组:
可以自定义一个API分组来实现限流(自定义API分组是一个细粒度的限流规则)
//配置初始化的限流参数
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("shop_product_api").setCount(1).setIntervalSec(1));
rules.add(new GatewayFlowRule("shop_order_api").setCount(1).setIntervalSec(1));
GatewayRuleManager.loadRules(rules);
}
//自定义API分组
@PostConstruct
private void initCustomizedApis(){
Set<ApiDefinition> definitions = new HashSet<>();
//定义小组1
ApiDefinition api1 = new ApiDefinition("shop_product_api")
.setPredicateItems(new HashSet<ApiPredicateItem>(){{
//以/product/product/api1开头的请求
add(new ApiPathPredicateItem().setPattern("/product/product/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
//定义小组2
ApiDefinition api2 = new ApiDefinition("shop_order_api")
.setPredicateItems(new HashSet<ApiPredicateItem>(){{
//完全匹配/order/order2/message
add(new ApiPathPredicateItem().setPattern("/order/order2/message"));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
在一秒钟内多次访问
也可以看到限流启作用了。
原文始发于微信公众号(Java技术前沿):微服务实战:Gateway 服务网关限流
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/299660.html