通过Kong网关实现Spring Cloud微服务的接口级别限流实现方案
1. 整体架构
客户端 → Kong网关 → Spring Cloud微服务 (限流策略)2. Kong安装与配置
2.1 安装Kong(Docker方式)
# docker-compose.ymlversion:'3.7'services:kong:image:kong:3.4environment:KONG_DATABASE:postgresKONG_PG_HOST:postgresKONG_PG_DATABASE:kongKONG_PG_USER:kongKONG_PG_PASSWORD:kongKONG_PROXY_ACCESS_LOG:/dev/stdoutKONG_ADMIN_ACCESS_LOG:/dev/stdoutKONG_PROXY_ERROR_LOG:/dev/stderrKONG_ADMIN_ERROR_LOG:/dev/stderrKONG_ADMIN_LISTEN:0.0.0.0:8001ports:-"8000:8000"# 代理端口-"8443:8443"# SSL代理-"8001:8001"# 管理APIdepends_on:-postgrespostgres:image:postgres:13environment:POSTGRES_DB:kongPOSTGRES_USER:kongPOSTGRES_PASSWORD:kong3. 配置Spring Cloud微服务路由
3.1 添加Service(服务)
# 创建Spring Cloud微服务对应的Servicecurl-X POST http://localhost:8001/services\--dataname=user-service\--dataurl='http://user-service:8080'\--datahost='user-service'\--datapath='/user-service'# 或使用Kong的声明式配置3.2 添加Route(路由)
# 为用户服务添加路由curl-X POST http://localhost:8001/services/user-service/routes\--data"paths[]=/api/users"\--data"strip_path=false"4. 接口级别限流配置
4.1 全局限流插件(针对整个服务)
# 启用限流插件(按IP限流)curl-X POST http://localhost:8001/services/user-service/plugins\--dataname=rate-limiting\--data config.second=10\# 每秒10次--data config.minute=100\# 每分钟100次--data config.hour=1000\# 每小时1000次--data config.policy=local\# 本地限流策略--data config.limit_by=ip# 按IP限流4.2 特定路由限流(接口级别)
# 为特定接口(如登录接口)配置更严格的限流curl-X POST http://localhost:8001/routes/{route-id}/plugins\--dataname=rate-limiting\--data config.second=2\# 每秒2次--data config.minute=20\# 每分钟20次--data config.limit_by=consumer# 按消费者限流4.3 声明式配置示例(YAML格式)
# kong.yaml_format_version:"3.0"services:-name:user-serviceurl:http://user-service:8080routes:-name:user-api-routepaths:["/api/users"]strip_path:falseplugins:-name:rate-limitingconfig:second:20minute:100hour:1000limit_by:ippolicy:local-name:user-login-routepaths:["/api/users/login"]strip_path:falseplugins:-name:rate-limitingconfig:second:5minute:30hour:200limit_by:ip-name:order-serviceurl:http://order-service:8081routes:-name:create-order-routepaths:["/api/orders/create"]plugins:-name:rate-limitingconfig:second:1# 创单接口更严格minute:30limit_by:consumer5. 高级限流配置
5.1 基于消费者(API Key)的限流
# 创建消费者(API客户端)curl-X POST http://localhost:8001/consumers\--datausername=app-client-1# 为消费者创建API Keycurl-X POST http://localhost:8001/consumers/app-client-1/key-auth\--datakey=apikey-123456# 为特定消费者设置限流curl-X POST http://localhost:8001/consumers/app-client-1/plugins\--dataname=rate-limiting\--data config.second=50\--data config.minute=20005.2 使用Redis集群实现分布式限流
# kong.yaml 片段plugins:-name:rate-limitingconfig:second:100policy:redisredis_host:redis-clusterredis_port:6379redis_password:passwordredis_timeout:2000redis_database:0limit_by:ip5.3 响应头配置
curl-X POST http://localhost:8001/services/user-service/plugins\--dataname=rate-limiting\--data config.second=10\--data config.minute=100\--data config.hide_client_headers=false\# 显示限流头信息--data config.fault_tolerant=true# 限流服务故障时继续6. Spring Cloud集成配置
6.1 Spring Cloud Gateway配置(备选方案)
# application.ymlspring:cloud:gateway:routes:-id:user-serviceuri:lb://user-servicepredicates:-Path=/api/users/**filters:-name:RequestRateLimiterargs:redis-rate-limiter.replenishRate:10# 每秒令牌数redis-rate-limiter.burstCapacity:20# 突发容量redis-rate-limiter.requestedTokens:1# 每次请求消耗key-resolver:"#{@userKeyResolver}"6.2 自定义Key解析器
@ConfigurationpublicclassRateLimiterConfig{@BeanpublicKeyResolveruserKeyResolver(){returnexchange->{// 按用户ID限流StringuserId=exchange.getRequest().getHeaders().getFirst("X-User-Id");returnMono.just(Objects.requireNonNullElse(userId,"anonymous"));};}@BeanpublicKeyResolveripKeyResolver(){// 按IP限流returnexchange->Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());}}7. 监控与告警
7.1 查看限流统计
# 查看所有限流插件curlhttp://localhost:8001/plugins|jq'.data[] | select(.name=="rate-limiting")'# 查看特定服务的限流状态curlhttp://localhost:8001/services/user-service/plugins7.2 Prometheus监控
# 启用Prometheus插件curl-X POST http://localhost:8001/plugins \--data name=prometheus7.3 Grafana仪表板
# 监控指标包括:# - kong_http_status{service="user-service", route="login"}# - kong_bandwidth# - kong_latency# - kong_rate_limiting_remaining8. 最佳实践建议
8.1 限流策略分层
# 三层限流策略:# 1. 全局层:每个IP 1000次/小时# 2. 服务层:每个服务 500次/小时# 3. 接口层:关键接口 100次/小时8.2 应对突发流量
# 配置突发容量curl-X POST http://localhost:8001/services/user-service/plugins\--dataname=rate-limiting\--data config.second=10\--data config.minute=100\--data config.fault_tolerant=true\--data config.redis_database=08.3 优雅降级
# 结合其他插件plugins:-name:rate-limitingconfig:second:100-name:response-ratelimiting# 响应限流config:limits.sms.minute:5-name:proxy-cache# 缓存降级config:content_type:["application/json"]9. 测试限流效果
# 测试脚本foriin{1..15};doresponse=$(curl-s -o /dev/null -w"%{http_code}"http://localhost:8000/api/users/login)echo"请求$i: 状态码$response"# 查看响应头curl-I http://localhost:8000/api/users/login|grep-i"rate-limit"done# 预期输出:# 前10个请求返回200# 第11个开始返回429 Too Many Requests总结
通过Kong网关实现Spring Cloud微服务的接口级别限流有以下优势:
- 灵活配置:支持服务级别、路由级别、消费者级别的精细控制
- 多种策略:支持本地、Redis集群、数据库等多种限流策略
- 高性能:Kong基于OpenResty(Nginx+Lua),性能出色
- 易于管理:提供RESTful管理API和声明式配置
- 生态丰富:支持插件扩展,可结合认证、日志、监控等
