soul网关源码学习14-rate_limiter插件解析
目标:
- 跑通rate_limiter插件
- 理解rate_limiter插件底层原理
一、运行项目
- 本地启动
redis
- 启动
admin
- 启动
bootstrap
- 启动
http-example
,用来测试限流插件
二、测试限流插件
- 在没用rate_limiter插件的情况下,我们先用jmeter来测试一下10个并发请求的响应情况。
可以看到10个请求全部请求成功。
- 接下来引入
rate_limiter
插件,在管理后台中开启插件,填入redis
地址和密码,这里用的是redis
单机,所以mode选择standalone
模式。
- 创建选择器和规则,这里测试
/http/order/findById
接口 - capacity指的是令牌桶的容量,这里表示令牌桶只能容纳1个令牌。
- rate指的是生成令牌的速率,这里表示1秒生成1个令牌。
- 用jmeter再测试一次,发现触发了限流,只有一个请求能请求成功。符合我们的预期,1秒内生成了一个令牌,在1秒内的10个并发请求只有一个能请求成功,当然请求比较慢的情况也有可能不止一个。
- 修改一下配置,把令牌桶容量改为100,速率改为5,再同样的进行10个并发的请求。
- 这里为了方便查看,把其他打印的日志先去掉,可以看到剩余的令牌数从99减到了90,消耗了10个令牌。
- 再进行一次并发请求,发现剩余令牌数并不是从99减到90,而是中途又新增了令牌。
- 可以仔细看一下时间,生成令牌的时候是以秒为间隔时间的,所以看下图,在52秒的时候,令牌数从99减到95,然后到53秒的时候,又新增了5个令牌,加上自己消耗了一个,所以又变成99了。
- 把并发数改为110,再请求一次,发现有5个请求被拒绝。
- 因为令牌桶容量为100,当发起110个请求时,本来应该是要拒绝掉10个请求的,但是刚好在那一秒内又生成了5个新的令牌,所以最终只拒绝掉5个请求。
所以,100个令牌,发起10个并发请求之后,有可能是剩余90个,有可能是大于90个小于100个。发起110个并发请求之后,有可能是拒绝掉5个请求,也有可能不是5个。
三、源码解析
- handle这里打上断点进来,有17个插件,这里我们看关键的RateLimiter插件
- 还是之前的链式调用,触发限流的话直接返回结果,没有触发的话继续执行后面的调用链。
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
<