对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

Guava Ratelimiter官方文档:https://guava.dev/releases/snapshot-jre/api/docs/
rate-limiter
源码: https://gitee.com/god007/rate-limiter.git
介绍
api qps限流工具,这里仅实现注解的方式对rest api进行tps(qps)限流,可指定参数为条件
使用说明
打包:mvn package,mvn deploy 上传到私有仓库
- 1.springboot项目依赖
<dependency>
<groupId>com.tydic.ratelimiter</groupId>
<artifactId>rate-limiter</artifactId>
<version>1.0-RELEASE</version>
</dependency>
- 2.springboot 启动类加入扫描路径
@ComponentScan({"com.tydic.ratelimiter","com.xxx"})
- 3.Controller的api方法上加入注解
/** * perSecond = 每秒放入桶中的令牌数,默认最大即不限流 * timeOut = 1 在一秒的时间内如果有许可则成功,没有则失败并返回errMsg定义的报文 * errMsg = 并发超出后 相应错误信息,默认为 "{\"code\":500,\"msg\":\"服务器繁忙,请稍后再试!\"}" * params = 根据参数决定是否做限流,默认为 {} * @return */ @RateLimit( perSecond = 10, errMsg = "{\"rspCode\":500,\"rspDesc\":\"服务器繁忙,请稍后再试!\"}", params = { @GetParam(name = "provinceCode",value = "370") } ) @GetMapping("test") @ResponseBody public Rsp testApi(HttpServletRequest request){ Rsp rsp = BaseRspUtils.createSuccessRsp("ok"); log.info("testApi : {}",rsp); return rsp; }
- 4.注解说明
perSecond: 每秒放入桶中的令牌数,默认值为: Double.MAX_VALUE
timeOut: 在s秒的时间内如果有许可则成功,没有则失败并返回errMsg定义的报文 默认值为: 1
errMsg: 并发超出后 相应错误信息,默认值为: "{"code":500,"msg":"服务器繁忙,请稍后再试!"}"
params: 根据get参数决定是否做限流 定义 @GetParam[] ,默认值为: {}
- 4.1 @GetParam
name: 参数名
value: 参数值