请访问原文: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的依赖,如下:

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-gateway</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.csp</groupId>
  7. <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
  8. <version>1.6.0</version>
  9. </dependency>

新建一个application.yml配置文件,用来配置路由:

  1. server:
  2. port: 2001
  3. spring:
  4. application:
  5. name: spring-cloud-gateway
  6. cloud:
  7. gateway:
  8. routes:
  9. - id: path_route
  10. uri: http://cxytiandi.com
  11. predicates:
  12. - Path=/course

配置了Path路由,等会使用 http://localhost:2001/course 进行访问即可。

增加一个GatewayConfiguration 类,用于配置Gateway限流要用到的类,目前是手动配置的方式,后面肯定是可以通过注解启用,配置文件中指定限流规则的方式来使用,当然这部分工作会交给Spring Cloud Alibaba来做,后面肯定会发新版本的,大家耐心等待就行了。

  1. @Configuration
  2. public class GatewayConfiguration {
  3. private final List<ViewResolver> viewResolvers;
  4. private final ServerCodecConfigurer serverCodecConfigurer;
  5. public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
  6. ServerCodecConfigurer serverCodecConfigurer) {
  7. this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
  8. this.serverCodecConfigurer = serverCodecConfigurer;
  9. }
  10. /**
  11. * 配置SentinelGatewayBlockExceptionHandler,限流后异常处理
  12. * @return
  13. */
  14. @Bean
  15. @Order(Ordered.HIGHEST_PRECEDENCE)
  16. public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
  17. return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
  18. }
  19. /**
  20. * 配置SentinelGatewayFilter
  21. * @return
  22. */
  23. @Bean
  24. @Order(-1)
  25. public GlobalFilter sentinelGatewayFilter() {
  26. return new SentinelGatewayFilter();
  27. }
  28. @PostConstruct
  29. public void doInit() {
  30. initGatewayRules();
  31. }
  32. /**
  33. * 配置限流规则
  34. */
  35. private void initGatewayRules() {
  36. Set<GatewayFlowRule> rules = new HashSet<>();
  37. rules.add(new GatewayFlowRule("path_route")
  38. .setCount(1) // 限流阈值
  39. .setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
  40. );
  41. GatewayRuleManager.loadRules(rules);
  42. }
  43. }

我们定义的资源名称是path_route,也就是application.yml中的路由ID,一致就行。

在一秒钟内多次访问http://localhost:2001/course就可以看到限流启作用了。

3.2 指定参数限流

上面的配置是针对整个路由来限流的,如果我们只想对某个路由的参数做限流,那么可以使用参数限流方式:

  1. rules.add(new GatewayFlowRule("path_route")
  2. .setCount(1)
  3. .setIntervalSec(1)
  4. .setParamItem(new GatewayParamFlowItem()
  5. .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("vipType")
  6. )
  7. );

通过指定PARAM_PARSE_STRATEGY_URL_PARAM表示从url中获取参数,setFieldName指定参数名称

3.3 自定义API分组

假设我有下面两个路由,我想让这两个路由共用一个限流规则,那么我们可以自定义进行组合:

  1. - id: path2_route
  2. uri: http://cxytiandi.com
  3. predicates:
  4. - Path=/article
  5. - id: path3_route
  6. uri: http://cxytiandi.com
  7. predicates:
  8. - Path=/blog/**

自定义分组代码:

  1. private void initCustomizedApis() {
  2. Set<ApiDefinition> definitions = new HashSet<>();
  3. ApiDefinition api1 = new ApiDefinition("customized_api")
  4. .setPredicateItems(new HashSet<ApiPredicateItem>() {{
  5. // article完全匹配
  6. add(new ApiPathPredicateItem().setPattern("/article"));
  7. // blog/开头的
  8. add(new ApiPathPredicateItem().setPattern("/blog/**")
  9. .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_PREFIX));
  10. }});
  11. definitions.add(api1);
  12. GatewayApiDefinitionManager.loadApiDefinitions(definitions);
  13. }

然后我们需要给customized_api这个资源进行配置:

  1. rules.add(new GatewayFlowRule("customized_api")
  2. .setCount(1)
  3. .setIntervalSec(1)
  4. );

3.4 自定义异常提示

前面我们有看到,当触发限流后页面显示的是Blocked by Sentinel: FlowException,正常情况下,就算给出提示也要跟后端服务的数据格式一样,如果你后端都是JSON格式的数据,那么异常的提示也要是JSON的格式,所以问题来了,我们怎么去自定义异常的输出?

前面我们有配置SentinelGatewayBlockExceptionHandler,我的注释写的限流后异常处理,我们可以进去看下源码就知道是不是异常处理了。下面贴出核心的代码:

  1. private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
  2. return response.writeTo(exchange, contextSupplier.get());
  3. }
  4. @Override
  5. public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
  6. if (exchange.getResponse().isCommitted()) {
  7. return Mono.error(ex);
  8. }
  9. // This exception handler only handles rejection by Sentinel.
  10. if (!BlockException.isBlockException(ex)) {
  11. return Mono.error(ex);
  12. }
  13. return handleBlockedRequest(exchange, ex)
  14. .flatMap(response -> writeResponse(response, exchange));
  15. }

重点在于writeResponse这个方法,我们只要把这个方法改掉,返回自己想要返回的数据就行了,可以自定义一个SentinelGatewayBlockExceptionHandler的类来实现。

比如:

  1. public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {
  2. // ........
  3. }

然后复制SentinelGatewayBlockExceptionHandler中的代码到JsonSentinelGatewayBlockExceptionHandler 中,只改动writeResponse一个方法即可。

  1. private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
  2. ServerHttpResponse serverHttpResponse = exchange.getResponse();
  3. serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
  4. byte[] datas = "{\"code\":403,\"msg\":\"限流了\"}".getBytes(StandardCharsets.UTF_8);
  5. DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
  6. return serverHttpResponse.writeWith(Mono.just(buffer));
  7. }

最后将配置的SentinelGatewayBlockExceptionHandler改成JsonSentinelGatewayBlockExceptionHandler 。

  1. @Bean
  2. @Order(Ordered.HIGHEST_PRECEDENCE)
  3. public JsonSentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
  4. return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
  5. }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: 阿里Sentinel支持Spring Cloud Gateway的实现

本文地址: http://www.cppcns.com/ruanjian/java/257764.html

阿里Sentinel支持Spring Cloud Gateway的实现相关推荐

  1. Alibaba Sentinel对接Spring Cloud Gateway关于不显示API管理及请求链路的坑附带解决方案

    在调试Sentinel对接Scg网关的时候,出现了一个比较坑的现象,就是网关菜单,不显示请求链路和API管理的菜单项,这个问题主要是由于,Sentinel的dashboard前端sidebar.js的 ...

  2. Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用

    Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...

  3. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...

  4. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战

    文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...

  5. 【云原生微服务>SCG网关篇十二】Spring Cloud Gateway集成Sentinel API实现多种限流方式

    文章目录 一.前言 二.Gateway集成Sentinel API 0.集成Sentinel的核心概念 1)GatewayFlowRule 和 ApiDefinition 2)GatewayFlowR ...

  6. Spring Cloud Gateway 原生支持接口限流该怎么玩

    关于pig: 基于Spring Cloud.oAuth2.0开发基于Vue前后分离的开发平台,支持账号.短信.SSO等多种登录,提供配套视频开发教程. 关于 Spring Cloud Gateway ...

  7. 实战 Spring Cloud Gateway 之限流篇

    来源:https://www.aneasystone.com/archives/2020/08/spring-cloud-gateway-current-limiting.html 话说在 Sprin ...

  8. 搭建一套ASP.NET Core+Nacos+Spring Cloud Gateway项目

    前言 伴随着随着微服务概念的不断盛行,与之对应的各种解决方案也层出不穷.这毕竟是一个信息大爆发的时代,各种编程语言大行其道,各有各的优势.但是有一点未曾改变,那就是他们服务的方式,工作的时候各司其职, ...

  9. Sentinel 成为 Spring Cloud 官方推荐的主流熔断降级方案

    近日,Sentinel 贡献的 spring-cloud-circuitbreaker-sentinel  模块正式被Spring Cloud社区合并至 Spring Cloud Circuit Br ...

  10. 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...

最新文章

  1. 以OpenGL/ES视角介绍gfx-hal(Vulkan) Framebuffer接口使用
  2. 在Linux下进行Apache+tomcat整合
  3. swing GeneralPath::cubicTo绘制平滑曲线
  4. python文字教程-Python在图片中添加文字的两种方法
  5. 霍金的预言正在实现,我们已经离不开人工智能,而它们在脱离控制
  6. 文件不混淆_Android Studio配置反混淆
  7. UI超实用通用图标素材模板
  8. 使用truffle 创建代币合约 使用ganache部署私有链 以及使用Atom 进行合约代码开发
  9. 笨鸟都没有先飞怎么办。。。
  10. lol更新显示正在连接服务器,wegame更新游戏显示正在连接服务器
  11. python 批量修改文件夹和子文件夹的名称
  12. centos服务器磁盘清理
  13. ES3、ES5、ES6、ES2016、ES2017、ES2018、ES2019
  14. 京东商城SPU、SKU是如何设计的
  15. Unity2D游戏制作常用方法
  16. QT5.12静态编译手册
  17. 传感器响应时间与滤波器截止频率的关系
  18. Win10清理鼠标右键新建菜单
  19. Windows开发之——平板手机作为电脑摄像头
  20. 跨浏览器书签同步(Floccus + WebDav)

热门文章

  1. windows 上面的tensorflow-GPU、cuda、cudnn 安装
  2. 分布式系统下数据一致性
  3. 5月上旬香港域名总量动态:大幅度下降 净减6466个
  4. 教你使用Wine在Linux上运行Windows软件
  5. 给我的两个小站点带点外链
  6. ConnectionString 最简便写法 for MSSQL 2005 EXPRESS
  7. directX9SDK中提取的9个DLL文件
  8. linux网络分析之回环网卡
  9. 立下2019年的Flag,鞭策自己,使命宣言
  10. linux下类似Bus Hound的工具