题目
如何设计API网关的分布式限流方案?
信息
- 类型:问答
- 难度:⭐⭐
考点
限流算法选择,分布式系统协调,高可用设计,网关核心功能
快速回答
设计API网关的分布式限流方案需考虑:
- 算法选择:令牌桶/漏桶算法,支持突发流量
- 分布式协调:Redis集群或分布式缓存存储计数
- 限流维度:支持API/用户/IP等多维度限流
- 降级策略:返回429状态码或服务降级
- 动态配置:支持运行时调整限流阈值
1. 核心原理
在分布式系统中,API网关作为流量入口,需通过限流保护后端服务:
- 令牌桶算法:以固定速率生成令牌,请求获取令牌才能通过
- 漏桶算法:以恒定速率处理请求,超出容量则拒绝
- 分布式计数:使用Redis等中间件存储全局访问计数
2. 实现方案示例(Redis + Lua)
// 使用Redis+Lua实现原子限流
public boolean allowRequest(String apiKey, int limit, int intervalSec) {
String luaScript = "local current = redis.call('incr', KEYS[1])\n" +
"if current == 1 then\n" +
" redis.call('expire', KEYS[1], ARGV[1])\n" +
"end\n" +
"return current <= tonumber(ARGV[2])";
// KEYS[1]=限流key, ARGV[1]=过期时间, ARGV[2]=限流阈值
Object result = jedis.eval(luaScript, 1, "rate_limit:" + apiKey,
String.valueOf(intervalSec), String.valueOf(limit));
return (Long)result == 1L;
}3. 最佳实践
- 分层限流:全局限流 + 服务级限流 + API级限流
- 动态配置:集成配置中心(如Nacos)实时更新规则
- 熔断降级:结合Hystrix/Sentinel实现服务熔断
- 流量整形:突发流量平滑处理(如Guava RateLimiter)
4. 常见错误
- 单点瓶颈:未使用分布式存储导致计数不准确
- 时间窗口不同步:固定窗口导致边界突发流量(需滑动窗口)
- 无降级策略:直接返回错误影响用户体验
- 资源耗尽:未限制Redis Key数量导致内存溢出
5. 扩展知识
- 集群限流:通过Redis Cluster分片减轻压力
- 自适应限流:根据系统负载动态调整阈值(如TCP BBR算法)
- 热点探测:实时监控自动识别热点API进行防护
- 云原生方案:Envoy网关的局部限流 + 全局限流服务