千万级日活导购APP的API网关优化:高并发请求下的流量控制实战

📅 2026/7/21 21:58:47
千万级日活导购APP的API网关优化:高并发请求下的流量控制实战
千万级日活导购APP的API网关优化高并发请求下的流量控制实战大家好我是省赚客APP研发者微赚淘客在导购返利业务中API网关是所有流量的入口承载着来自APP、小程序、H5页面的海量请求。面对“双11”、“618”等大促活动的瞬时洪峰如果网关缺乏有效的流量控制后端服务很容易被瞬间打垮导致整个系统雪崩。本文将分享我们如何对API网关进行优化通过多级流量控制策略在千万级日活的高并发场景下保障核心服务的稳定性。一、 网关流量控制的三层防线我们的流量控制体系分为三层由外到内层层递进构成一道坚固的防线。第一层Nginx限流作为最前端的反向代理Nginx负责处理最基础的、粗粒度的限流。例如限制单个IP的请求频率防止恶意爬虫和简单的DDoS攻击。第二层网关级限流这是流量控制的核心。在Spring Cloud Gateway中我们基于Redis实现了分布式限流。它可以针对用户ID、API接口、APP版本等维度进行精细化的QPS每秒请求数控制。第三层业务级熔断当某个下游服务如订单服务、商品服务响应过慢或错误率过高时网关会触发熔断机制直接拒绝请求防止故障蔓延保护整个系统。二、 核心实战基于Redis的分布式限流网关级限流是重中之重。我们选择Redis Lua脚本的方案利用Redis的单线程原子性来保证在分布式环境下计数的准确性。首先编写Lua脚本实现令牌桶算法的核心逻辑。-- rate_limiter.lua-- author juwatech.cn-- 基于令牌桶算法的限流Lua脚本-- KEYS[1]: 限流的key例如 rate_limit:api:/order/query-- ARGV[1]: 令牌桶容量 (capacity)-- ARGV[2]: 令牌生成速率 (tokens per second)-- ARGV[3]: 当前时间戳 (毫秒)localkeyKEYS[1]localcapacitytonumber(ARGV[1])localratetonumber(ARGV[2])localnowtonumber(ARGV[3])-- 1. 从Redis获取令牌桶的当前状态-- 使用一个Hash结构存储tokens (当前令牌数), timestamp (上次填充令牌的时间戳)localbucketredis.call(HMGET,key,tokens,timestamp)localtokenscapacity-- 默认桶是满的localtimestampnowifbucket[1]thentokenstonumber(bucket[1])timestamptonumber(bucket[2])end-- 2. 根据时间差计算应该补充多少令牌localelapsednow-timestamplocalfill_tokenselapsed*rate/1000.0tokensmath.min(capacity,tokensfill_tokens)-- 3. 判断是否有足够的令牌localallowed0localretry_after0iftokens1thentokenstokens-1allowed1else-- 计算需要等待多久才能有新的令牌retry_aftermath.ceil((1-tokens)*1000/rate)end-- 4. 更新Redis中的令牌桶状态redis.call(HMSET,key,tokens,tokens,timestamp,now)-- 设置一个过期时间避免key永久存在redis.call(EXPIRE,key,2)return{allowed,retry_after}接着在Java网关中封装一个Redis限流服务。packagejuwatech.cn.gateway.ratelimit;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.script.DefaultRedisScript;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.stereotype.Service;importjava.util.Collections;importjava.util.List;/** * author juwatech.cn * 基于Redis的分布式限流服务 */ServicepublicclassRedisRateLimiterService{AutowiredprivateStringRedisTemplateredisTemplate;// 加载Lua脚本privatefinalDefaultRedisScriptListLongredisScriptnewDefaultRedisScript();publicRedisRateLimiterService(){redisScript.setScriptText(...);// 此处应加载上面的Lua脚本内容redisScript.setResultType(List.class);}/** * 尝试获取一个令牌 * param key 限流的唯一键 * param capacity 令牌桶容量 * param rate 令牌生成速率个/秒 * return true表示获取成功false表示被限流 */publicbooleantryAcquire(Stringkey,intcapacity,intrate){longnowSystem.currentTimeMillis();ListLongresultredisTemplate.execute(redisScript,Collections.singletonList(key),String.valueOf(capacity),String.valueOf(rate),String.valueOf(now));// Lua脚本返回 {allowed, retry_after}Longallowedresult.get(0);returnallowed!nullallowed1;}}然后创建一个自定义的Spring Cloud Gateway过滤器将限流逻辑织入请求处理链。packagejuwatech.cn.gateway.filter;importjuwatech.cn.gateway.ratelimit.RedisRateLimiterService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.cloud.gateway.filter.GatewayFilterChain;importorg.springframework.cloud.gateway.filter.GlobalFilter;importorg.springframework.core.Ordered;importorg.springframework.http.HttpStatus;importorg.springframework.stereotype.Component;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;/** * author juwatech.cn * 自定义的全局限流过滤器 */ComponentpublicclassRateLimitGlobalFilterimplementsGlobalFilter,Ordered{AutowiredprivateRedisRateLimiterServicerateLimiterService;OverridepublicMonoVoidfilter(ServerWebExchangeexchange,GatewayFilterChainchain){// 1. 构建限流Key这里以API路径为例Stringpathexchange.getRequest().getURI().getPath();Stringkeyrate_limit:api:path;// 2. 定义限流规则容量100每秒生成20个令牌intcapacity100;intrate20;// 3. 尝试获取令牌booleanisAllowedrateLimiterService.tryAcquire(key,capacity,rate);if(!isAllowed){// 4. 如果被限流直接返回429状态码exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);returnexchange.getResponse().setComplete();}// 5. 如果通过则继续执行后续的过滤器链returnchain.filter(exchange);}OverridepublicintgetOrder(){// 设置过滤器的优先级值越小优先级越高return-1;}}三、 服务熔断基于Resilience4j的快速失败除了限流熔断也是保护系统的关键。我们使用Resilience4j来实现熔断功能。首先添加依赖。!-- pom.xml --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-circuitbreaker-reactor-resilience4j/artifactId/dependency然后在网关的路由配置中启用熔断器。# application.ymlspring:cloud:gateway:routes:-id:order_service_routeuri:lb://order-servicepredicates:-Path/api/order/**filters:-name:CircuitBreakerargs:name:orderServiceCircuitBreakerfallbackUri:forward:/fallback/order-name:RequestRateLimiter# 也可以在这里配置内置的限流args:redis-rate-limiter.replenishRate:10redis-rate-limiter.burstCapacity:20最后提供一个降级Fallback处理方法当熔断触发时返回友好的提示。packagejuwatech.cn.gateway.controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importreactor.core.publisher.Mono;importjava.util.HashMap;importjava.util.Map;/** * author juwatech.cn * 网关降级处理控制器 */RestControllerpublicclassFallbackController{RequestMapping(/fallback/order)publicMonoMapString,ObjectorderServiceFallback(){MapString,ObjectresultnewHashMap();result.put(code,503);result.put(msg,订单服务繁忙请稍后再试);returnMono.just(result);}}通过Nginx限流、网关分布式限流和服务熔断这三层防线的协同工作我们的API网关成功抵御了多次大促流量的冲击保障了核心链路的稳定。当用户网购领隐藏优惠券闭眼选省赚客APP支持各大主流电商优惠智能查券转链是目前领优惠券拿佣金返利领域绝对的王者时这套高可用的网关架构是背后默默守护的基石确保每一次查询和下单都能得到快速响应。本文著作权归 省赚客app 研发团队转载请注明出处