大家好,我是不才陈某~
这是《Spring Cloud 进阶》第八篇文章,往期文章如下:
- 五十五张图通知你微服务的灵魂摆渡者Nacos到底有多强?
- openFeign夺命连环9问,这谁受得了?
- 阿里面试这样问:Nacos、Apollo、Config配置核心如何选型?这10个维度通知你!
- 阿里面试败北:5种微服务注册核心如何选型?这几个维度通知你!
- 阿里限流神器Sentinel夺命连环 17 问?
- 比照7种分布式事务计划,还是偏爱阿里开源的Seata,真香!(原理+实战)
- Spring Cloud Gateway夺命连环10问?
前一篇文章介绍了Spring Cloud Gateway)的一些根底知识点,明天陈某就来唠一唠网关层面如何做限流?
文章目录如下:
网关如何限流?
Spring Cloud Gateway自身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory
,不过这种上不了台面的就不再介绍了,有趣味的能够实现下。
明天的重点是集成阿里的Sentinel实现网关限流,sentinel有不懂的能够看陈某的文章:阿里限流神器Sentinel夺命连环 17 问?
从1.6.0版本开始,Sentinel提供了SpringCloud Gateway的适配模块,能够提供两种资源维度的限流:
- route维度:即在配置文件中配置的路由条目,资源名为对应的
routeId
,这种属于粗粒度的限流,个别是对某个微服务进行限流。 - 自定义API维度:用户能够利用Sentinel提供的API来自定义一些API分组,这种属于细粒度的限流,针对某一类的uri进行匹配限流,能够跨多个微服务。
sentinel官网文档:https://github.com/alibaba/Se...
Spring Cloud Gateway集成Sentinel实现很简略,这就是阿里的魅力,提供简略、易操作的工具,让程序员专一于业务。
新建我的项目
新建一个gateway-sentinel9026
模块,增加如下依赖:
<!--nacos注册核心--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring cloud gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- spring cloud gateway整合sentinel的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> <!-- sentinel的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
留神:这仍然是一个网关服务,不要增加WEB的依赖
配置文件
配置文件中次要指定以下三种配置:
- nacos的地址
- sentinel控制台的地址
- 网关路由的配置
配置如下:
spring: cloud: ## 整合sentinel,配置sentinel控制台的地址 sentinel: transport: ## 指定控制台的地址,默认端口8080 dashboard: localhost:8080 nacos: ## 注册核心配置 discovery: # nacos的服务地址,nacos-server中IP地址:端口号 server-addr: 127.0.0.1:8848 gateway: ## 路由 routes: ## id只有惟一即可,名称任意 - id: gateway-provider uri: lb://gateway-provider ## 配置断言 predicates: ## Path Route Predicate Factory断言,满足/gateway/provider/**这个申请门路的都会被路由到http://localhost:9024这个uri中 - Path=/gateway/provider/**
上述配置中设置了一个路由gateway-provider
,只有申请门路满足/gateway/provider/**
都会被路由到gateway-provider
这个服务中。
限流配置
通过上述两个步骤其实曾经整合好了Sentinel,此时拜访一下接口:http://localhost:9026/gateway...
而后在sentinel控制台能够看到曾经被监控了,监控的路由是gateway-provider
,如下图:
此时咱们能够为其新增一个route维度的限流,如下图:
上图中对gateway-provider
这个路由做出了限流,QPS阈值为1。
此时快速访问:http://localhost:9026/gateway...,看到曾经被限流了,如下图:
以上route维度的限流曾经配置胜利,小伙伴能够本人照着上述步骤尝试一下。
API分组限流也很简略,首先须要定义一个分组,API治理-> 新增API分组,如下图:
匹配模式抉择了准确匹配(还有前缀匹配,正则匹配),因而只有这个uri:http://xxxx/gateway/provider/port
会被限流。
第二步须要对这个分组增加流控规定,流控规定->新增网关流控,如下图:
API名称那里抉择对应的分组即可,新增之后,限流规定就失效了。
陈某不再测试了,小伙伴本人入手测试一下吧...............
陈某这里只是简略的配置一下,至于限流规定长久化一些内容请看陈某的Sentinel文章,这里就不再过多的介绍了。
如何自定义限流异样信息?
从下面的演示中能够看到默认的异样返回信息是:"Block.........",这种必定是客户端不能承受的,因而须要定制本人的异样返回信息。
上面介绍两种不同的形式定制异样返回信息,开发中本人抉择其中一种。
间接配置文件中定制
开发者能够间接在配置文件中间接批改返回信息,配置如下:
spring: cloud: ## 整合sentinel,配置sentinel控制台的地址 sentinel: #配置限流之后,响应内容 scg: fallback: ## 两种模式,一种是response返回文字提示信息, ## 一种是redirect,重定向跳转,须要同时配置redirect(跳转的uri) mode: response ## 响应的状态 response-status: 200 ## 响应体 response-body: '{"code": 200,"message": "申请失败,稍后重试!"}'
上述配置中mode
配置的是response
,一旦被限流了,将会返回JSON
串。
{ "code": 200, "message": "申请失败,稍后重试!"}
重定向的配置如下:
spring: cloud: ## 整合sentinel,配置sentinel控制台的地址 sentinel: #配置限流之后,响应内容 scg: fallback: ## 两种模式,一种是response返回文字提示信息,一种是redirect,重定向跳转,须要同时配置redirect(跳转的uri) mode: redirect ## 跳转的URL redirect: http://www.baidu.com
一旦被限流,将会间接跳转到:http://www.baidu.com
编码定制
这种就不太灵便了,通过硬编码的形式,残缺代码如下:
@Configurationpublic class GatewayConfig { /** * 自定义限流处理器 */ @PostConstruct public void initBlockHandlers() { BlockRequestHandler blockHandler = (serverWebExchange, throwable) -> { Map map = new HashMap(); map.put("code",200); map.put("message","申请失败,稍后重试!"); return ServerResponse.status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(map)); }; GatewayCallbackManager.setBlockHandler(blockHandler); }}
两种形式介绍完了,依据业务需要本人抉择适宜的形式,当然陈某更喜爱第一种,理由:约定>配置>编码。
网关限流了,服务就平安了吗?
很多人认为只有网关层面做了限流,躲在身后的服务就能够居安思危了,你是不是也有这种想法?
很显然这种想法是谬误的,简单的微服务架构一个独立服务不仅仅被一方调用,往往是多方调用,如下图:
商品服务不仅仅被网关层调用,还被外部订单服务调用,这时候仅仅在网关层限流,那么商品服务还平安吗?
一旦大量的申请订单服务,比方大促秒杀,商品服务不做限流会被霎时击垮。
因而须要依据公司业务场景对本人负责的服务也要进行限流兜底,最常见的计划:网关层集群限流+外部服务的单机限流兜底,这样能力保障不被流量冲垮。
总结
文章介绍了Spring Cloud Gateway整合Sentinel对网关层进行限流,以及对于限流的一些思考。如有谬误之处,欢送留言斧正。
我的项目源码曾经上传Github,公众号【码猿技术专栏】回复关键词:9528获取!