服务限流降级

https://segmentfault.com/a/1190000015967922

高并发的线上服务, 有时候面对突发流量, 比如流量突然激增,服务扛不住了,类似这种场景,需要有一个防御措施, 常用的有降级和限流

降级:比如一些热点事件, 当前服务器压力很大, 可以置顶一些降级策略,最简单的比如,随机丢弃一定的用户不走推荐逻辑; 或者用一些低资源消耗的计算逻辑替换线上的逻辑等等, 主要是策略导向的; 被降级的用户请求,可能推荐结果不是那么的最优, 但可尽量的保证正常的访问。 同等的资源下, 服务更多的用户, 以适当的牺牲用户体验为代价

限流: 服务的抗压能力是一定的,在请求量突然增大, 可通过限流策略,来丢弃部分请求,保证服务的稳定。比如服务扛压是1w,  当前有4个上游在同时调用我们的服务,其中有一个服务优先级特别高,需要优先保证正常访问,此时,需要根据一定的策略来限制当前的流量不超过1w,常用的限流策略有令牌桶和漏桶

令牌桶:按照固定的速度, 给令牌桶里面放令牌, 每个服务发请求过来的时候, 需要去桶里面拿对应的令牌,如果没有令牌了,则丢弃本次请求; 有点像混合型共厂,即生产电话,也生产电脑。给的原料多了就快一些,少了就慢一些,都能跑起来,但是再优秀的机器,也有一个上限, 还是不能太多了,如果真的太多了,就要限制速度,到底是生产电脑还是手机呢?就早一个桶,两边分别去拿对应的速率生产就好了

漏桶:按照固定的速度从桶里释放请求,新来的请求放进桶里,如果桶满了,就直接丢弃;有点像工厂里面的生产机器,按照固定的速度生产螺丝钉, 如果前面堆的原料太多,已经溢出了,新原料就放不进来了,而流水线的产出速度稳定不变,慢悠悠的吐出就可以了,没什么压力

<think>好的,用户之前询问了Redis中并发执行Lua脚本的问题,现在转向了gateway的限流降级操作案例。我需要先理解用户的需求。可能用户正在设计或维护一个分布式系统,需要处理高并发下的流量控制和故障处理。限流降级是微服务架构中的常见策略,用于保证系统稳定性。 用户可能想知道具体的实现案例,比如使用哪些工具,如何配置,以及实际应用中的注意事项。他们可能对不同的限流算法(如令牌桶、漏桶)和降级策略(如熔断、服务降级)感兴趣。同时,用户可能希望了解在实际项目中如何集成这些功能,比如使用Spring Cloud Gateway、Sentinel或者Nginx等。 需要确定用户的技术栈,但用户没有明确说明,所以需要涵盖常见的解决方案。比如,Spring Cloud Gateway适合Java生态,Sentinel是阿里开流的,Nginx作为反向代理也很常用。此外,还要提到云服务提供商的方案,如AWS的API Gateway,这对使用云服务的用户可能有帮助。 另外,用户可能关心如何配置限流规则,比如每秒请求数,如何根据IP或用户进行限流降级后的处理策略,比如返回默认值或错误信息。案例部分需要具体,最好有代码示例或配置示例,这样用户更容易理解。 还需要注意潜在的问题,比如限流导致的用户体验下降,如何监控和调整限流阈值,降级后如何恢复服务等。此外,分布式系统中的一致性问题,比如在集群环境下如何同步限流状态,可能需要使用Redis等中间件。 最后,总结部分需要强调限流降级的重要性,以及如何根据具体场景选择合适的工具和策略。确保回答结构清晰,分点说明,覆盖不同工具和实际案例,帮助用户全面理解并应用这些技术。</think>以下是网关限流降级操作的典型实现方案及实践案例解析,分层说明核心原理与实施方法: --- ### 一、**基础限流模型** #### 1. **令牌桶算法(Token Bucket)** $$ \text{令牌生成速率} = \frac{\text{桶容量}}{\text{时间窗口}} $$ ```yaml # Spring Cloud Gateway 配置示例 spring: cloud: gateway: routes: - id: user_service uri: lb://user-service predicates: - Path=/api/users/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 100 # 每秒100令牌 redis-rate-limiter.burstCapacity: 200 # 突发容量200 key-resolver: "#{@ipKeyResolver}" # 按IP限流 ``` #### 2. **滑动窗口计数** $$ \text{允许请求数} = \sum_{i=1}^{n} \text{子窗口计数} \leq \text{阈值} $$ ```java // Sentinel 滑动窗口实现核心逻辑 public class SlidingWindow { private AtomicReferenceArray<WindowWrap> array; // 时间窗口数组 private int windowLength; // 子窗口时长(毫秒) } ``` --- ### 二、**降级策略分类** #### 1. **熔断降级(Circuit Breaker)** 状态转换逻辑: ``` CLOSED → (失败率超阈值) → OPEN → (冷却时间后) → HALF-OPEN ``` | 指标 | 阈值示例 | 监控周期 | |--------------------|------------|-----------| | 慢调用比例 | > 50% | 10秒 | | 异常比例 | > 60% | 5秒 | | 最小请求数 | 10次 | - | #### 2. **返回预设值降级** ```xml <!-- Sentinel 降级规则配置 --> <flowRule> <resource>getUserInfo</resource> <grade>1</grade> <!-- 异常数模式 --> <count>5</count> <!-- 触发阈值 --> <timeWindow>30</timeWindow> <fallbackClass>com.example.UserFallback</fallbackClass> </flowRule> ``` --- ### 三、**分布式场景实践** #### 1. **Redis集群限流同步** ```lua -- 分布式令牌桶Lua脚本 local tokens_key = KEYS[1] -- 令牌桶key local timestamp_key = KEYS[2] -- 最后更新时间key local rate = tonumber(ARGV[1]) -- 令牌生成速率 local capacity = tonumber(ARGV[2])-- 桶容量 local now = tonumber(ARGV[3]) -- 当前时间戳 local requested = tonumber(ARGV[4])-- 请求令牌数 local last_tokens = tonumber(redis.call("get", tokens_key)) or capacity local last_refreshed = tonumber(redis.call("get", timestamp_key)) or now local delta = math.max(0, now - last_refreshed) local new_tokens = math.min(capacity, last_tokens + delta * rate) local allowed = new_tokens >= requested local result = { allowed, new_tokens } if allowed then new_tokens = new_tokens - requested end redis.call("setex", tokens_key, math.ceil(capacity/rate), new_tokens) redis.call("setex", timestamp_key, math.ceil(capacity/rate), now) return result ``` #### 2. **Nginx限流配置** ```nginx http { limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s; server { location /api/ { limit_req zone=api_limit burst=50 nodelay; proxy_pass http://backend; # 超时降级处理 error_page 504 = @fallback; } location @fallback { return 503 '{"code":503,"msg":"服务暂时不可用"}'; } } } ``` --- ### 四、**云原生方案示例** #### 1. **AWS API Gateway 阶梯限流** ```json { "throttling": { "burstLimit": 1000, // 突发请求上限 "rateLimit": 500 // 持续请求速率(次/秒) }, "quota": { "limit": 10000, // 日请求总量限制 "offset": 0, // 配额周期偏移量 "period": "DAY" // 配额周期类型 } } ``` #### 2. **Envoy 动态限流** ```yaml # envoy限流过滤器配置 http_filters: - name: envoy.filters.http.ratelimit typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit domain: apigateway failure_mode_deny: true rate_limit_service: grpc_service: envoy_grpc: cluster_name: rate_limit_cluster ``` --- ### 五、**监控与调优** #### 1. 关键监控指标 | 指标类型 | PromQL示例 | 告警阈值 | |------------------|-------------------------------------|---------------| | 限流触发次数 | rate(gateway_requests_limited[5m]) | > 10次/分钟 | | 平均响应时间 | histogram_quantile(0.95, rate(...)) | > 500ms | | 熔断器状态 | sum(circuit_breaker_state) | OPEN状态持续>30s | #### 2. 动态规则调整 ```java // Sentinel 动态规则更新示例 List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule("resA") .setGrade(RuleConstant.FLOW_GRADE_QPS) .setCount(100); // 动态调整QPS阈值 FlowRuleManager.loadRules(rules); ``` --- ### 六、**典型故障案例** **案例背景**:电商大促期间订单服务超载 **应对措施**: 1. **分级降级**: - 一级降级:关闭商品推荐服务 - 二级降级:简化订单确认页数据 - 三级降级:启用静态兜底页面 2. **流量调度**: ```bash # 使用HAProxy动态调整权重 echo "set weight order_service/backend1 30" | socat stdio /var/run/haproxy.stat ``` 3. **效果验证**: - API成功率从65%提升至92% - 系统负载下降40% --- **最佳实践总结**: 1. **分层防御**:边缘节点(CDN)→ 网关层 → 服务层逐级限流 2. **动态生效**:结合配置中心实现规则热更新 3. **灰度发布**:新规则先作用于5%流量验证 4. **熔断恢复**:采用指数退避策略尝试恢复 5. **压测验证**:定期通过Chaos Engineering测试系统极限 通过合理组合这些技术手段,可使网关系统在1ms内完成限流判断,支持百万级QPS场景,将服务不可用时间减少至传统架构的1/10。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值