Apache ShenYu网关流量控制:基于QPS的限流实现
系统高峰期流量突增常导致服务过载,Apache ShenYu网关提供基于令牌桶算法的限流机制,通过控制每秒查询率(QPS)保护后端服务。本文详解限流实现原理与配置方法。
限流核心组件解析
ShenYu限流功能主要通过以下模块协作实现:
1. 限流规则配置模型
RateLimiterHandle.java定义限流核心参数:
@Data
public class RateLimiterHandle {
private double replenishRate; // 令牌生成速率(个/秒)
private double burstCapacity; // 令牌桶容量
private boolean loged; // 是否记录限流日志
}
replenishRate:控制QPS基础值,如设为100表示每秒生成100个令牌burstCapacity:允许突发流量的最大令牌数,通常设为replenishRate的2-3倍
2. Redis限流实现
RedisRateLimiter.java基于Redis实现分布式限流,核心逻辑:
public Mono<RateLimiterResponse> isAllowed(final String id,
final double replenishRate,
final double burstCapacity) {
List<String> keys = getKeys(id); // 生成Redis键:request_rate_limiter.{id}.tokens
List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
Instant.now().getEpochSecond() + "", "1");
// 执行Lua脚本实现原子性限流判断
Flux<List<Long>> resultFlux = this.redisTemplate.execute(this.script, keys, scriptArgs);
}
通过Redis Lua脚本保证限流判断的原子性,避免分布式环境下的并发问题。
令牌桶算法工作原理
ShenYu采用令牌桶算法控制流量,流程如下:
关键特性:
- 令牌匀速生成,控制长期QPS
- 允许短期突发流量(不超过burstCapacity)
- 分布式环境下通过Redis共享令牌状态
限流插件配置步骤
1. 启用限流插件
在管理后台启用RateLimiter插件,配置Redis连接信息:
soul:
plugin:
rate-limiter:
enabled: true
redis:
host: localhost
port: 6379
2. 配置限流规则
通过PluginController.java提供的API创建限流规则:
{
"pluginId": "rate_limiter",
"selectorId": "1",
"ruleId": "1001",
"handle": "{\"replenishRate\":100,\"burstCapacity\":200,\"loged\":true}"
}
3. 规则生效范围
- 全局级别:直接配置插件默认规则
- 选择器级别:通过SelectorController.java配置某类资源的限流
- 规则级别:针对具体接口路径精细化配置
实际应用场景
1. 普通接口保护
对查询类接口设置基础限流:
{
"replenishRate": 200,
"burstCapacity": 400
}
2. 秒杀接口特殊配置
秒杀场景配置令牌桶容量为秒杀商品库存:
{
"replenishRate": 50,
"burstCapacity": 100 // 对应100件库存
}
3. 限流监控
通过influxdb/MonitorDO.java记录限流指标,结合Grafana可视化流量趋势。
扩展与调优建议
- 动态调整速率:通过Admin API实时更新replenishRate应对流量变化
- 预热模式:初始阶段逐步提高令牌生成速率,避免冷启动流量冲击
- 分布式部署:确保Redis集群高可用,避免限流单点故障
- 熔断降级配合:结合HystrixHandle.java实现多级保护
限流配置需根据业务场景持续优化,建议通过压测确定合理的replenishRate和burstCapacity值,既保证服务稳定性,又不影响用户体验。完整实现可参考soul-web/plugin/function/RateLimiterPlugin.java。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



