- 对于请求的限流主要有三种方式:计数器、漏桶算法、令牌桶算法。
计数器
记录每个请求的次数,限制请求每秒最多请求多少次,否则失效。这个方式比较简单粗暴。最明显的弊端就是,我限制了1秒内最多请求100次,但是在前10ms内已经请求完了100次,那么之后990ms相当于是空闲的,请求也无法再过来了。
漏桶算法
请求放在桶里面,排队放行。不管流量多大,多余的请求始终要在桶内排队,当桶内请求装满以后,之后的请求再也无法进来了。而且当瞬时请求很多的时候,漏桶算法也无法应对。实现方面:使用一个队列存储前台过来的请求,然后使用ScheduleExecutorService
来定期从队列中获取请求,然后并发执行。
令牌桶算法
当请求通过gateway的时候,都要去一个桶里面拿令牌,拥有令牌的请求才给予放行。桶里面的令牌是限量的。比如桶里面有100个令牌,当这100个令牌被领取完后,后面的只能排队等待令牌工厂生产下一批令牌。生产令牌的速度可以根据实际业务需求和QPS定制。令牌桶算法主要有两个核心点:
- 令牌工厂:负责生产令牌放到令牌桶中,生产速率可控。
- 令牌桶:用于存放令牌的地方,请求从令牌桶中获取令牌。
实现方式:令牌工厂可以使用一个线程,根据一定的速率生产令牌,然后将令牌放在令牌桶中。每来一个请求就从令牌桶中获取令牌,然后放行。当令牌桶中的令牌获取完以后,可以重试获取令牌,知道获取到为止,也可以直接返回错误。
Spring Cloud Gateway限流
Spring Cloud Gateway自带了令牌桶算法的限流策略。但是需要额外依赖redis和reactive包。引用包后,需要在配置文件中配置spring.cloud.gateway.routes.filters
,然后实现KeyResolver
。KeyResolver
可以从多个维度去做限流策略:ip地址、用户层面、接口uri层面。具体实现方式: Spring Cloud Gateway 限流操作