一、背景
网关的出现用来帮助后端开发者减少通用工作量的开发,如rpc接口的限流,限额,鉴权等。本文提供一种利用spring cloud gateway来实现的全局限流实现方案。
限额方案参考:juejin.cn/post/704210…
二、限流方案
当前常用的限流有两种,基于漏斗和基于令牌桶。基于漏斗的限流算法在流量到来时,会先将流量放入一个漏洞中,然后均匀放行。一般适合于调用三方系统,避免当前系统流量过大打垮三方api。基于令牌桶的算法是在流量到来时会先获取令牌,获取到令牌后就可以直接放行,同时运行部分突增流量。相关算法网上资料很多,可以进一步做详细了解。
本文限流采用guava提供的RateLimiter来,RateLimiter采用令牌桶算法来实现。
三、整体架构
整体架构如下图所示。
在数据库中配置每个api不同维度的限流信息。网关异步定时拉取不同维度qps的配置。同时获取集群中网关实例个数,计算出每个网关的对每个api的每个维度的qps限制。
四、实现
数据库表名:api_rate_limit_config,表结构:
CREATE TABLE `api_rate_limit_config` (
`id` bigint(20) NOT NULL,
`api` varchar(255) NOT NULL,
`rate_key` varchar(255) NOT NULL,
`qps` int(11) NOT NULL,
`create_time` bigint(20) DEFAULT NULL,
`update_time` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
api记录通过网关的api名称,rate_key表示每个api的维度信息,一个api可以有多个不同维度rate_key的配置。
例如要配置api为rate.limit.test.api的最大流量为100。则有如下配置。
id | api | rate_key | qps |
---|---|---|---|
1 | rate.limit.test.api | apiId:rate.limit.test.api | 100 |
请求时的curl如下所示。
curl --location --request GET 'http://localhost:8100/gateway/rateTest?apiId=rate.limit.test.api'
如果qps超过100,则会提示限流信息。
详细代码参考:github.com/Tyoukai/fla…