Spring cloud 之多种方式限流
在频繁的网络请求时,服务有时候也会受到很大的压力,尤其是那种网络攻击,非法的。这样的情形有时候需要作一些限制。例如:限制对方的请求,这种限制可以有几个依据:请求IP、用户唯一标识、请求的接口地址等等。
当前限流的方式也很多:Spring cloud 中在网关本身自带限流的一些功能,基于 redis 来做的。同时,阿里也开源了一款:限流神器 Sentinel。今天我们主要围绕这两块来实战微服务的限流机制。
首先讲 Spring cloud 原生的限流功能,因为限流可以是对每个服务进行限流,也可以对于网关统一作限流处理。
一、实战基于 Spring cloud Gateway 的限流
pom.xml引入依赖:
其基础是基于redis,所以:
接下来需要注入限流策略的 bean:
这里引入ipKeyResolver、apiKeyResolver、userKeyResolver三种策略,可以利用注解 @Primary 来决定其中一个被使用。
注入bean后,需要在配置中备用:
这里是在原有的路由基础上加入 RequestRateLimiter限流过滤器,包括三个参数:
其中 replenishRate,其含义表示允许每秒处理请求数;
burstCapacity 表示允许在一秒内处理的最大请求数;
key-resolver 这里采用请求 IP 限流,利用SPEL 表达式取对应的 bean
写一个小脚本来压测一下:
上面两个脚本分别对2个服务进行压测,打印结果:
从上面可以看到,执行后,会出现调用失败的情况,状态变为429 (Too Many Requests) 。
二、基于阿里开源限流神器:Sentinel
首先引入依赖:
在配置文件 application.yaml 文件中配置,需要新增2个配置:
其中,这里面配置了一个服务:spring.cloud.sentinel.transport.dashboard,配置的是 sentinel 的 Dashboard 地址。同时 spring.cloud.sentinel.transport.port 这个端口配置会在应用对应的机器上启动一个Http Server,该 Server 会与 Sentinel 控制台做交互。
Sentinel 默认为所有的 HTTP 服务提供限流埋点,上面配置完成后自动完成所有埋点,只需要控制配置限流规则即可。
这里我们讲下通过注解来给指定接口函数加上限流埋点,写一个RestController,在接口函数上加上注解 @SentinelResource:
以上代码部分完成了,接下来先安装SentinelDashBoard,Sentinel DashBoard下载地址:https://github.com/alibaba/Sentinel/releases 。
下载完成后,命令启动:
默认启动端口为8080,访问 IP:8080,就可以显示 Sentinel 的登录界面,用户名与密码均为sentinel。登录 Dashboard 成功后,多次访问接口"/getToken",可以在 Dashboard 看到相应数据,这里不展示了。接下来可以设置接口的限流功能,在 “+流控” 按钮点击打开设置界面,设置阈值类型为 qps,单机阈值为5。
浏览器重复请求 http://10.10.15.5:5556/admin-web/api/user/getToken 如果超过阀值就会出现如下界面信息:
此时,就看到Sentinel 限流起作用了,可以加上 spring.cloud.sentinel.scg.fallback 为sentinel 限流后的响应配置,亦可自定义限流异常信息:
这里讲下注解 @SentinelResource 包含以下属性:
value:资源名称,必需项;
entryType:入口类型,可选项(默认为 EntryType.OUT);
blockHandler:blockHandlerClass中对应的异常处理方法名,参数类型和返回值必须和原方法一致;
blockHandlerClass:自定义限流逻辑处理类
Sentinel 限流逻辑处理完毕了,但每次服务重启后,之前配置的限流规则就会被清空。因为是内存形式的规则对象。所以下面就讲下用 Sentinel 的一个特性 ReadableDataSource 获取文件、数据库或者配置中心设置限流规则,目前支持 Apollo、Nacos、ZK 配置来管理。
首先回忆一下,一条限流规则主要由下面几个因素组成:
resource:资源名,即限流规则的作用对象,即为注解 @SentinelResource 的value;
count:限流阈值;grade:限流阈值类型(QPS 或并发线程数);
limitApp:流控针对的调用来源,若为 default 则不区分调用来源;
strategy:基于调用关系的限流策略;
controlBehavior:流量控制效果(直接拒绝、排队等待、匀速器模式)
理解了意思,接下来通过文件来配置:
在resources新建一个文件,比如 flowrule.json 添加限流规则:
重新启动项目,出现如下日志说明成功:
如果采用 Nacos 作为配置获取限流规则,可在文件中加如下配置:
以上即为限流的两种方式。
结束福利
开源实战利用 k8s 作微服务的架构设计代码:https://gitee.com/damon_one/spring-cloud-k8s
,欢迎大家 star,多多指教。
关于作者
笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合docker、k8s做微服务容器化,自动化部署等一站式项目部署、落地。Go 语言学习,k8s研究,边缘计算框架 KubeEdge 等。公众号程序猿Damon
发起人。个人微信 MrNull008
,欢迎來撩。
欢迎关注 InfoQ: https://www.infoq.cn/profile/1905020/following/user
欢迎关注公众号:
版权声明: 本文为 InfoQ 作者【Damon】的原创文章。
原文链接:【http://xie.infoq.cn/article/cb487f3402bf3bdfaba2b6005】。文章转载请联系作者。
评论