如今高并发已经成为每个项目必须考虑的一点,但是对于用户量大的项目来说,在大并发量下,系统很有可能撑不住压力,导致数据库宕机甚至导致系统崩溃。
限流就成为解决这类问题的首选答案,如今市面上已经有了很多很成熟的框架,例如Alibaba的sentinel,Google提供的RateLimiter。在阅读了RateLimiter的源码后,我基于令牌桶模型实现了一种面向切面的限流方式,并且自己实现了底层的令牌桶模型(还需要优化)
1.项目所需依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.自定义注解RateLimiter
3.自定义实现底层令牌桶
基于令牌桶思想,按每1/qps的速率像令牌桶中添加令牌,当令牌桶中的令牌为空的时候,进行限流。我的实现中并没有真的具体出一个集合用来定时存入令牌桶,而是采用记录本次请求访问时间,与上一次请求访问时间,通过他们差值与传入令牌桶速率的关系来存入令牌,空间复杂度更低。
3.切面类
效果展示
我使用了Jmeter压测工具,对限流能力进行压测
这里我设置qps=100,使用jmeter工具每秒发起150个线程请求接口,重复两次
这个工具目前还存在有很多问题,我计划近期内进行优化,并且使用nacos的动态配置,尝试能否在程序运行时修改qps的值。