阿里Sentinel支持Spring Cloud Gateway的实现
请访问原文:http://www.cppcns.com/ruanjian/java/257764.html
这篇文章主要介绍了阿里Sentinel支持Spring Cloud Gateway的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
1. 前言
4月25号,Sentinel 1.6.0 正式发布,带来 Spring Cloud Gateway 支持、控制台登录功能、改进的热点限流和注解 fallback 等多项新特性,该出手时就出手,紧跟时代潮流,昨天刚发布,今天我就要给大家分享下如何使用!
2. 介绍(本段来自Sentinel文档)
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/ 和 /baz/ 的都归到 my_api 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。
其中网关限流规则 GatewayFlowRule 的字段解释如下:
- resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
- resourceMode:规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)还是用户在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是 route。
- grade:限流指标维度,同限流规则的 grade 字段
- count:限流阈值
- intervalSec:统计时间窗口,单位是秒,默认是 1 秒
- controlBehavior:流量整形的控制效果,同限流规则的 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:为后续参数匹配特性预留,目前未实现。
用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则,或通过 GatewayRuleManager.register2Property(property) 注册动态规则源动态推送(推荐方式)。
3. 使用
3.1 快速体验
首先你的有一个Spring Cloud Gateway的项目,如果没有,新建一个,增加Gateway和sentinel-spring-cloud-gateway-adapter的依赖,如下:
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
- <dependency>
- <groupId>com.alibaba.csp</groupId>
- <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
- <version>1.6.0</version>
- </dependency>
新建一个application.yml配置文件,用来配置路由:
- server:
- port: 2001
- spring:
- application:
- name: spring-cloud-gateway
- cloud:
- gateway:
- routes:
- - id: path_route
- uri: http://cxytiandi.com
- predicates:
- - Path=/course
配置了Path路由,等会使用 http://localhost:2001/course 进行访问即可。
增加一个GatewayConfiguration 类,用于配置Gateway限流要用到的类,目前是手动配置的方式,后面肯定是可以通过注解启用,配置文件中指定限流规则的方式来使用,当然这部分工作会交给Spring Cloud Alibaba来做,后面肯定会发新版本的,大家耐心等待就行了。
- @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;
- }
- /**
- * 配置SentinelGatewayBlockExceptionHandler,限流后异常处理
- * @return
- */
- @Bean
- @Order(Ordered.HIGHEST_PRECEDENCE)
- public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
- return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
- }
- /**
- * 配置SentinelGatewayFilter
- * @return
- */
- @Bean
- @Order(-1)
- public GlobalFilter sentinelGatewayFilter() {
- return new SentinelGatewayFilter();
- }
- @PostConstruct
- public void doInit() {
- initGatewayRules();
- }
- /**
- * 配置限流规则
- */
- private void initGatewayRules() {
- Set<GatewayFlowRule> rules = new HashSet<>();
- rules.add(new GatewayFlowRule("path_route")
- .setCount(1) // 限流阈值
- .setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
- );
- GatewayRuleManager.loadRules(rules);
- }
- }
我们定义的资源名称是path_route,也就是application.yml中的路由ID,一致就行。
在一秒钟内多次访问http://localhost:2001/course就可以看到限流启作用了。
3.2 指定参数限流
上面的配置是针对整个路由来限流的,如果我们只想对某个路由的参数做限流,那么可以使用参数限流方式:
- rules.add(new GatewayFlowRule("path_route")
- .setCount(1)
- .setIntervalSec(1)
- .setParamItem(new GatewayParamFlowItem()
- .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("vipType")
- )
- );
通过指定PARAM_PARSE_STRATEGY_URL_PARAM表示从url中获取参数,setFieldName指定参数名称
3.3 自定义API分组
假设我有下面两个路由,我想让这两个路由共用一个限流规则,那么我们可以自定义进行组合:
- - id: path2_route
- uri: http://cxytiandi.com
- predicates:
- - Path=/article
- - id: path3_route
- uri: http://cxytiandi.com
- predicates:
- - Path=/blog/**
自定义分组代码:
- private void initCustomizedApis() {
- Set<ApiDefinition> definitions = new HashSet<>();
- ApiDefinition api1 = new ApiDefinition("customized_api")
- .setPredicateItems(new HashSet<ApiPredicateItem>() {{
- // article完全匹配
- add(new ApiPathPredicateItem().setPattern("/article"));
- // blog/开头的
- add(new ApiPathPredicateItem().setPattern("/blog/**")
- .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_PREFIX));
- }});
- definitions.add(api1);
- GatewayApiDefinitionManager.loadApiDefinitions(definitions);
- }
然后我们需要给customized_api这个资源进行配置:
- rules.add(new GatewayFlowRule("customized_api")
- .setCount(1)
- .setIntervalSec(1)
- );
3.4 自定义异常提示
前面我们有看到,当触发限流后页面显示的是Blocked by Sentinel: FlowException,正常情况下,就算给出提示也要跟后端服务的数据格式一样,如果你后端都是JSON格式的数据,那么异常的提示也要是JSON的格式,所以问题来了,我们怎么去自定义异常的输出?
前面我们有配置SentinelGatewayBlockExceptionHandler,我的注释写的限流后异常处理,我们可以进去看下源码就知道是不是异常处理了。下面贴出核心的代码:
- private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
- return response.writeTo(exchange, contextSupplier.get());
- }
- @Override
- public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
- if (exchange.getResponse().isCommitted()) {
- return Mono.error(ex);
- }
- // This exception handler only handles rejection by Sentinel.
- if (!BlockException.isBlockException(ex)) {
- return Mono.error(ex);
- }
- return handleBlockedRequest(exchange, ex)
- .flatMap(response -> writeResponse(response, exchange));
- }
重点在于writeResponse这个方法,我们只要把这个方法改掉,返回自己想要返回的数据就行了,可以自定义一个SentinelGatewayBlockExceptionHandler的类来实现。
比如:
- public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {
- // ........
- }
然后复制SentinelGatewayBlockExceptionHandler中的代码到JsonSentinelGatewayBlockExceptionHandler 中,只改动writeResponse一个方法即可。
- private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
- ServerHttpResponse serverHttpResponse = exchange.getResponse();
- serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
- byte[] datas = "{\"code\":403,\"msg\":\"限流了\"}".getBytes(StandardCharsets.UTF_8);
- DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
- return serverHttpResponse.writeWith(Mono.just(buffer));
- }
最后将配置的SentinelGatewayBlockExceptionHandler改成JsonSentinelGatewayBlockExceptionHandler 。
- @Bean
- @Order(Ordered.HIGHEST_PRECEDENCE)
- public JsonSentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
- return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
- }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
本文标题: 阿里Sentinel支持Spring Cloud Gateway的实现
本文地址: http://www.cppcns.com/ruanjian/java/257764.html
阿里Sentinel支持Spring Cloud Gateway的实现相关推荐
- Alibaba Sentinel对接Spring Cloud Gateway关于不显示API管理及请求链路的坑附带解决方案
在调试Sentinel对接Scg网关的时候,出现了一个比较坑的现象,就是网关菜单,不显示请求链路和API管理的菜单项,这个问题主要是由于,Sentinel的dashboard前端sidebar.js的 ...
- Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用
Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战
文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...
- 【云原生微服务>SCG网关篇十二】Spring Cloud Gateway集成Sentinel API实现多种限流方式
文章目录 一.前言 二.Gateway集成Sentinel API 0.集成Sentinel的核心概念 1)GatewayFlowRule 和 ApiDefinition 2)GatewayFlowR ...
- Spring Cloud Gateway 原生支持接口限流该怎么玩
关于pig: 基于Spring Cloud.oAuth2.0开发基于Vue前后分离的开发平台,支持账号.短信.SSO等多种登录,提供配套视频开发教程. 关于 Spring Cloud Gateway ...
- 实战 Spring Cloud Gateway 之限流篇
来源:https://www.aneasystone.com/archives/2020/08/spring-cloud-gateway-current-limiting.html 话说在 Sprin ...
- 搭建一套ASP.NET Core+Nacos+Spring Cloud Gateway项目
前言 伴随着随着微服务概念的不断盛行,与之对应的各种解决方案也层出不穷.这毕竟是一个信息大爆发的时代,各种编程语言大行其道,各有各的优势.但是有一点未曾改变,那就是他们服务的方式,工作的时候各司其职, ...
- Sentinel 成为 Spring Cloud 官方推荐的主流熔断降级方案
近日,Sentinel 贡献的 spring-cloud-circuitbreaker-sentinel 模块正式被Spring Cloud社区合并至 Spring Cloud Circuit Br ...
- 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...
最新文章
- 以OpenGL/ES视角介绍gfx-hal(Vulkan) Framebuffer接口使用
- 在Linux下进行Apache+tomcat整合
- swing GeneralPath::cubicTo绘制平滑曲线
- python文字教程-Python在图片中添加文字的两种方法
- 霍金的预言正在实现,我们已经离不开人工智能,而它们在脱离控制
- 文件不混淆_Android Studio配置反混淆
- UI超实用通用图标素材模板
- 使用truffle 创建代币合约 使用ganache部署私有链 以及使用Atom 进行合约代码开发
- 笨鸟都没有先飞怎么办。。。
- lol更新显示正在连接服务器,wegame更新游戏显示正在连接服务器
- python 批量修改文件夹和子文件夹的名称
- centos服务器磁盘清理
- ES3、ES5、ES6、ES2016、ES2017、ES2018、ES2019
- 京东商城SPU、SKU是如何设计的
- Unity2D游戏制作常用方法
- QT5.12静态编译手册
- 传感器响应时间与滤波器截止频率的关系
- Win10清理鼠标右键新建菜单
- Windows开发之——平板手机作为电脑摄像头
- 跨浏览器书签同步(Floccus + WebDav)