Soul源码总结-01-30

  • 跑通ratelimiter插件
  • 能够对流量进行限制,控制
  • 总结

Demo

  1. 首先启动项目soul-admin以及soul-bootstrap,以soul-examples中的soul-example-http为例,注册到soul网关上。同时在soul-admin插件管理中心开启rate_limiter插件。由于开启限流插件需要开启redis,那么就需要现在本地开启redis服务。本次示例的redis是本地的redis单例。因此需要在rate_limiter中选择standalonemode并且配置相应的redis节点信息。在这里插入图片描述

启动服务顺序: soul-admin-->soul-bootstrap-->soul-examples-http-->redis-cluster(本地docker启动)

  1. 正确配置rate_limiter插件.
  • 配置selector在这里插入图片描述
  • 自定义相关规则在这里插入图片描述
    这里为了接下来更容易演示,将capacity设置为2,rate设置为1。
  1. 测试限流策略是否生效
  • 使用Postman进行测试, 对http://localhost:9195/http/order/findById?id=1进行测试转发在这里插入图片描述
    可以看到soul网关控制台打出以下日志:
2021-01-30 13:45:32.865  INFO 29956 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : rate_limiter selector success match , selector name :/rate_limiter
2021-01-30 13:45:32.866  INFO 29956 --- [-work-threads-1] o.d.soul.plugin.base.AbstractSoulPlugin  : rate_limiter rule success match , rule name :/rate_limiter_test
2021-01-30 13:45:32.891  INFO 29956 --- [oEventLoop-18-1] o.d.s.p.r.executor.RedisRateLimiter      : RateLimiter response:Response{allowed=true, tokensRemaining=1}
2021-01-30 13:45:32.892  INFO 29956 --- [oEventLoop-18-1] o.d.soul.plugin.base.AbstractSoulPlugin  : divide selector success match , selector name :/http
2021-01-30 13:45:32.897  INFO 29956 --- [oEventLoop-18-1] o.d.soul.plugin.base.AbstractSoulPlugin  : divide rule success match , rule name :/http/order/findById
2021-01-30 13:45:32.898  INFO 29956 --- [oEventLoop-18-1] o.d.s.plugin.httpclient.WebClientPlugin  : The request urlPath is http://172.19.0.1:8188/order/findById?id=1, retryTimes is 0

说明rate_limiter插件匹配成功。

  • 触发限流。我们可以选择工具压测或者我们可以手动触发限流器限流。这里为了更好地演示,使用手动触发。在这里插入图片描述
    并且在soul网关控制台看到以下日志输出:
2021-01-30 13:39:47.633  INFO 29956 --- [work-threads-22] o.d.soul.plugin.base.AbstractSoulPlugin  : rate_limiter selector success match , selector name :/rate_limiter
2021-01-30 13:39:47.633  INFO 29956 --- [work-threads-22] o.d.soul.plugin.base.AbstractSoulPlugin  : rate_limiter rule success match , rule name :/rate_limiter_test
2021-01-30 13:39:47.642  INFO 29956 --- [oEventLoop-18-1] o.d.s.p.r.executor.RedisRateLimiter      : RateLimiter response:Response{allowed=false, tokensRemaining=0}

说明限流器已经生效, rate_limiter插件已经跑通。

rate-limiter插件底层原理初探

rate-limiter插件和其他插件相同,都会执行 AbstractSoulPlugin 类的 execute() 方法,然后在RateLimiterPlugin中覆写doExecute方法,核心代码如下:在这里插入图片描述
从代码中可以看到如果redisRateLimiter判断可以执行,则该插件链可以继续执行,如果不可以,那么就返回429状态码表明已经发送太多请求,从而起到限流效果。
因此redisRateLimiter是整个限流处理中的核心类,我们着重看一下核心处理方法isAllowed在这里插入图片描述
关键代码

Flux<List<Long>> resultFlux = Singleton.INST.get(ReactiveRedisTemplate.class).execute(this.script, keys, scriptArgs);

说明redis执行lua脚本,并根据resultFlux来判断该插件是否执行还是中断并限流。lua脚本在路径META-INF/scripts/request_rate_limiter.lua可找到

local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])

lua脚本中的rate和capacity分别对应我们在soul-admin中设置的值。rate是redis指令牌桶的填充速率,capacity对应令牌桶可以保存的令牌数。
限流核心流程大概就是这样。那么rate-limiter-plugin又是如何和soul-admin数据同步并连接redis呢?
我们注意到在RateLimiterPluginDataHandler中会通过soul-admin同步来的pluginData的json字符串来parse生成RateLimiterConfig对象,里面包含了我们在soul-admin中配置的所有信息,包括master, mode, url, password等信息。然后通过Lettuce客户端来连接redis。核心代码如下在这里插入图片描述
在这里插入图片描述
至此,rate-limiter插件从上游到下游的路径已经基本打通。

总结

RateLimiterPlugin核心是ratelimiter通过redis+lua脚本执行令牌桶算法来判断是否应该对请求进行处理或者抛弃(即起到限流作用)令牌桶算法还需要进一步学习,具体可以参考redis-令牌桶算法介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值