1. Apache ShenYu RateLimiter插件概述
Apache ShenYu作为一款高性能的API网关,其RateLimiter插件是基于令牌桶算法实现的分布式限流组件。在实际生产环境中,我们经常需要借助Redis来实现集群级别的流量控制。这个方案最大的优势在于能够跨网关实例维护统一的计数器,避免单节点限流在集群环境下失效的问题。
我去年在电商大促期间就曾用这套方案成功抵御了突发流量冲击。当时峰值QPS达到12万,通过Redis集群+哨兵模式部署,配合ShenYu的RateLimiter插件,实现了毫秒级的精准限流。下面就把这套经过实战检验的配置方案完整分享出来。
2. 环境准备与插件启用
2.1 基础环境要求
- ShenYu 2.5.0及以上版本
- Redis 5.0+集群(建议6.x版本以获得更好性能)
- Java 8+运行环境
重要提示:Redis内存建议配置为预期限流QPS的2倍以上。例如要支持1万QPS的限流,Redis实例至少需要2GB内存。
2.2 插件启用步骤
- 在ShenYu Admin控制台找到"插件管理"
- 启用
rate_limiter插件 - 修改插件配置:
rate_limiter: mode: redis redis: host: 192.168.1.100:6379 password: yourpassword database: 0 timeout: 3000- 点击"同步配置"将设置推送到网关节点
3. Redis集群配置优化
3.1 连接池参数调优
在bootstrap.yml中添加以下配置:
spring: redis: lettuce: pool: max-active: 500 max-idle: 50 min-idle: 20 max-wait: 3000这个配置经过我们压力测试验证,在8核16G的网关节点上可以支持3万+的QPS。如果遇到Redis连接不足的错误,可以按比例增加max-active值。
3.2 Redis内存优化
执行以下Redis配置命令:
config set maxmemory 2gb config set maxmemory-policy allkeys-lru config rewrite这可以防止Redis内存溢出导致限流失效。我们曾经就遇到过因为没设置maxmemory,导致Redis内存暴涨最终崩溃的情况。
4. 限流规则配置实战
4.1 基础限流规则
在ShenYu Admin的"流量控制"页面添加规则:
{ "name": "order_api_limit", "selector": "order-service", "path": "/api/v1/order/**", "rate": 1000, "burst": 200, "timeUnit": "SECONDS" }这个配置表示:
- 每秒允许1000个请求
- 突发流量允许额外200个请求
- 适用于所有order-service下/api/v1/order/开头的接口
4.2 多维度限流配置
支持更复杂的场景:
{ "name": "user_api_limit", "selector": "user-service", "path": "/api/v1/user/*", "rate": 500, "burst": 100, "timeUnit": "SECONDS", "params": { "userId": "/5" } }这个配置会对每个userId的前5位进行分组限流,非常适合防止单个用户刷接口的情况。
5. 生产环境问题排查
5.1 常见错误处理
错误1:RedisConnectionFailureException
解决方案:
- 检查Redis集群状态
- 增加连接超时时间:
timeout: 5000错误2:NOAUTH Authentication required
确认redis密码配置正确:
password: your_actual_password5.2 监控指标解读
在ShenYu的/actuator/metrics端点可以查看:
shenyu_ratelimiter_request_total:总请求数shenyu_ratelimiter_limited_total:被限流请求数shenyu_ratelimiter_execution_latency:限流器执行延迟
当limited_total占比超过5%时,就需要考虑调整限流阈值了。
6. 性能优化技巧
6.1 Lua脚本优化
ShenYu默认使用的限流Lua脚本可以通过以下方式优化:
- 将脚本预加载到Redis:
redis-cli script load "$(cat /path/to/rate_limiter.lua)"- 在配置中使用返回的SHA1值:
redis: scriptSha: "a1b2c3d4e5f6..."这样每次限流检查可以减少网络传输开销,我们测试可以提升约30%的性能。
6.2 本地缓存降级
在网关的bootstrap.yml中添加:
rate_limiter: fallbackToLocal: true local: size: 10000 expire: 60s当Redis不可用时会自动降级到本地限流,虽然精度会下降,但能保证系统不会完全失去保护。
7. 高级应用场景
7.1 灰度发布限流
结合ShenYu的divide插件可以实现:
{ "name": "gray_release_limit", "selector": "gray-service", "path": "/api/v2/**", "rate": 100, "burst": 20, "timeUnit": "SECONDS", "matchMode": "header", "matchKey": "X-Gray-Release", "matchValue": "true" }这样可以对灰度流量单独限流,避免影响正式环境。
7.2 动态规则调整
通过ShenYu的Admin API可以实时修改限流规则:
curl -X PUT http://admin:123456@localhost:9095/plugin/rateLimiter/rule/{id} \ -H "Content-Type: application/json" \ -d '{"rate":2000}'我们在618大促时就通过脚本根据监控指标动态调整限流阈值,非常灵活。