限流算法(Rate Limiting)
目的:防止系统被突发流量冲垮,保护后端服务稳定性,确保“该服务的能服务,不该服务的拒绝掉”。
常见的限流算法有:
令牌桶算法(Token Bucket)
原理:
- 系统以固定速率往“桶”里放令牌(Token)。
- 每个请求需要获取一个令牌才能被处理。
- 如果桶里没有令牌,请求被拒绝或等待。
- 桶有最大容量,令牌满了就丢弃新生成的令牌(不会溢出)。
特点:
- 允许一定程度突发流量:只要桶里有令牌,可以瞬间处理多个请求(比如桶容量=100,可以瞬间处理 100 个请求)。
- 适合应对短时突发流量(如秒杀、热点新闻)。
- 实现简单,广泛用于 API 网关、Nginx、云服务商(如 AWS API Gateway)。
示例:
| |
漏桶算法(Leaky Bucket)
原理:
- 请求像“水”一样流入一个固定容量的“漏桶”。
- 桶以恒定速率“漏水”(即处理请求)。
- 如果桶满了,新来的请求会被丢弃(或排队等待,取决于实现)。
特点:
- 强制平滑输出:无论输入多猛,输出速率恒定。
- 更适合需要严格控制处理速率的场景(如硬件设备、支付网关)。
- 不允许突发流量 —— 即使桶是空的,也只能按固定速率处理。
与令牌桶对比:
| 特性 | 令牌桶 | 漏桶 |
|---|---|---|
| 是否允许突发 | 是 | ❌ 否 |
| 输出是否平滑 | ❌ 否(可突发) | 是(恒定速率) |
| 实现复杂度 | 简单 | 简单 |
| 适用场景 | API 限流、应对突发流量 | 网络流量整形、硬件控制 |
通常推荐令牌桶,因为它更灵活,兼顾突发与平滑。
熔断降级(Circuit Breaker)
目的:当下游服务不可用或响应过慢时,快速失败,避免请求堆积导致雪崩。
类比电路中的“保险丝” —— 出问题就“跳闸”,保护整个系统。
熔断器三态模型:
CLOSED(闭合):
- 正常状态,请求正常放行。
- 统计失败率(如错误率 > 50%),达到阈值 → 切换到 OPEN。
OPEN(打开):
- 熔断状态,所有请求直接失败,不调用下游。
- 启动一个“休眠时间窗”(如 5 秒),到期后 → 切换到 HALF_OPEN。
HALF_OPEN(半开):
- 尝试放行少量请求(试探下游是否恢复)。
- 若成功 → 恢复 CLOSED;若失败 → 回到 OPEN。
主流实现:
➤ Hystrix(Netflix,已停更,但原理经典)
- 提供熔断、降级、隔离(线程池/信号量)、监控等功能。
- 注解式使用(Java 生态):
1 2@HystrixCommand(fallbackMethod = "fallbackMethod") public String callService() { ... }
➤ Sentinel(阿里巴巴,推荐用于新项目)
- 支持流量控制、熔断降级、系统负载保护、热点参数限流。
- 轻量、高性能、支持集群流控。
- 提供 Dashboard 实时监控。
- Python 可通过
sentinel-pythonSDK 接入。
| |
服务降级策略(Service Degradation)
目的:在系统压力过大或部分服务不可用时,牺牲非核心功能,保障核心链路可用。
不是“系统挂了”,而是“有策略地简化服务”。
降级时如何保证用户体验?
我们采用分层降级策略:核心路径(如下单、支付)绝不降级;非核心路径(如推荐、评论)返回兜底数据或提示。前端配合展示友好文案,比如“推荐服务繁忙,稍后为您更新”,避免空白或报错。
降级触发条件:
- 熔断器打开
- 系统负载过高(CPU、内存、线程池满)
- 依赖服务超时或失败率高
- 人工配置开关(如大促期间主动降级)
常见降级方式:
返回兜底数据(Fallback)
- 调用失败 → 返回缓存数据、默认值、静态页
- 例:商品详情页调用推荐服务失败 → 返回“猜你喜欢”默认列表
关闭非核心功能
- 关闭评论、打分、推荐、广告等模块
- 例:双 11 期间关闭“用户足迹”、“个性化推荐”
页面降级(前端配合)
- 前端检测接口失败 → 展示简化版 UI 或提示语
- 例:首页瀑布流加载失败 → 显示“点击重试”按钮
延迟处理(异步化)
- 非实时功能转为异步:如发短信、写日志、积分计算
- 通过 MQ 削峰填谷
静态化/缓存前置
- 高频读接口 → Nginx 缓存 / CDN / Redis 缓存
- 降低后端压力
降级开关设计(重要!)
- 配置中心控制(如 Nacos、Apollo):动态开启/关闭降级策略
- 分层降级:按用户等级(VIP 优先)、按地域、按设备
- 自动化降级:根据监控指标(如错误率、RT)自动触发
- 人工干预入口:运维后台一键降级
总结图示
| |
熔断和限流有什么区别?
限流是“防进”,控制进入系统的请求量;熔断是“防出”,当下游服务异常时快速失败,防止线程阻塞和资源耗尽。两者常配合使用 —— 限流控制入口流量,熔断保护依赖调用。