限流、熔断与降级入门(含 Sentinel 实战)
结合课件第 3 章(3-1 ~ 3-9)的视频要点,整理一套面向初学者的服务保护指南,帮助理解“为什么需要限流、熔断和降级”,以及如何用 Sentinel 快速上手。
学习路线速览
- 3-1 理解服务雪崩与限流、熔断、降级的背景
- 3-2 Sentinel 与 Hystrix 对比,明确技术选型
- 3-3 Sentinel QPS 限流基础
- 3-4 预测型限流与冷启动
- 3-5 Throttling 配置演示
- 3-6 Sentinel 熔断降级策略
- 3-7 熔断策略——基于错误比率
- 3-8 降级策略——基于响应时间
- 3-9 Gin + Sentinel 实战限流
服务雪崩的成因
当突发流量超过系统承载力(例如系统容量 1k QPS 却突然涌入 2k QPS)时,会引发响应变慢、错误率飙升,继而拖垮更多依赖,形成“雪崩”。常见诱因:
- 流量突增:大促、热点新闻、爬虫等造成访问量暴涨。
- 依赖故障:下游服务延迟或挂掉,调用堆积。
- 资源耗尽:线程/连接/CPU 被占满,导致更多请求排队。
应对策略三件套:限流挡住洪水、熔断拉下断路器、降级提供兜底体验。
graph LR
A[突发流量] --> B(限流:削峰填谷)
B --> C{依赖正常?}
C -->|是| D[服务稳定运行]
C -->|否| E(熔断:暂时切断调用)
E --> F(降级:返回备用方案)
F --> D
限流:给入口加“闸门”
限流(Rate Limiting)通过控制单位时间内的请求数量或并发度,让系统在可控范围内运行。常见策略:
| 策略 | 场景 | 优点 | 可能副作用 |
|---|---|---|---|
| 固定窗口 QPS | 接口需要简单限速 | 实现简单 | 边界瞬时突刺 |
| 滑动窗口 | API 网关、统一出口 | 控制更平滑 | 计算稍复杂 |
| 漏桶(Leak Bucket) | 回放请求、削峰填谷 | 输出稳定 | 突发流量被排队 |
| 令牌桶(Token Bucket) | 允许部分突刺 | 指标灵活(QPS/并发) | 需要监控桶状态 |
限流提示语应友好:“当前访问人数较多,请稍后重试或关注通知”。
graph TD
subgraph 限流闸门
Tokens[令牌桶] -->|取令牌| Request[请求放行]
Request --> Service[核心服务]
end
Tokens -.超限.-> Fallback[返回 429 或排队提示]
熔断:让系统“精神焕发”
“熔断”类似电路断路器——当检测到错误率、响应时间等指标异常,就暂时切断调用,防止故障扩散。因为拉闸后系统可以喘口气恢复元气,课堂上也打趣称它让系统“精神焕发”。
Sentinel 支持三类熔断规则:
- 慢调用比例:超出设定耗时阈值的请求占比过高时触发。
- 异常比例:统计窗口内异常数占比超标时熔断。
- 异常数:在单位时间内异常总数达到阈值时熔断。
熔断后通常经历三个阶段:Open(全阻断) -> Half-Open(少量探测) -> Closed(恢复正常)。
降级:提供备用体验
当核心流程压力过大或依赖熔断时,降级策略给用户提供“简化但可用”的结果:
- 返回缓存或兜底数据(例如展示昨日库存)。
- 提示稍后处理,异步回调(订单排队、工单受理)。
- 将高成本功能临时关闭(例如关闭推荐列表,只保留基础搜索)。
降级重点是提前准备:文案、兜底接口、前端占位都要就绪。
Sentinel 速览
Sentinel 是阿里开源的高可用防护框架,核心价值:
- 统一控制台管理限流、熔断、降级、系统保护等规则。
- 支持 Java 与 Go,提供丰富的生态适配(Dubbo、Spring Cloud、Gin 等)。
- 具备实时监控、链路聚合、规则推送等能力。
Sentinel 结构示意:
graph LR
subgraph 控制台
Dashboard[Dashboard 控制台]
end
Dashboard -- 推送规则 --> DataSource[数据源/配置中心]
DataSource -- 动态规则 --> Sentinel[Sentinel 客户端]
Sentinel -- 上报指标 --> Dashboard
Sentinel --> App[业务应用]
Go 语言快速上手(以 Gin 项目为例)
- 安装依赖
bash
go get github.com/alibaba/sentinel-golang@latest
go get github.com/alibaba/sentinel-golang/pkg/adapters/gin
- 初始化 Sentinel
```go
package main
import (
"log"
"github.com/alibaba/sentinel-golang/api"
"github.com/alibaba/sentinel-golang/core/flow"
)
func initSentinel() {
if err := api.InitDefault(); err != nil {
log.Fatalf("init sentinel: %v", err)
}
_, err := flow.LoadRules([]*flow.Rule{
{
Resource: "GET:/api/orders",
MetricType: flow.QPS,
Count: 200,
ControlBehavior: flow.WarmUp,
WarmUpPeriodSec: 10,
WarmUpColdFactor: 3,
},
})
if err != nil {
log.Fatalf("load flow rules: %v", err)
}
}
<code>
<ol>
<li><strong>接入 Gin 中间件</strong></li>
</ol>
</code>go
r := gin.Default()
r.Use(sgin.SentinelMiddleware())
r.GET("/api/orders", func(c *gin.Context) {
if entry, blockErr := api.Entry("GET:/api/orders"); blockErr != nil {
c.JSON(429, gin.H{"code": 429, "msg": "拥挤,请稍后重试"})
return
} else {
defer entry.Exit()
}
c.JSON(200, gin.H{"orders": []string{"#1201", "#1202"}})
})
```
- 本地调试建议
- 使用
ab/wrk进行压测,验证限流是否生效。 - 观察日志和 Dashboard 中的实时 QPS、Block 指标。
Java 环境接入要点
<!-- Maven -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
@Configuration
public class SentinelConfig {
@PostConstruct
public void init() throws Exception {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("product_list");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(1000);
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
rule.setMaxQueueingTimeMs(500);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
结合 Spring Cloud Alibaba,可通过 @SentinelResource 标注降级回调方法。
Dashboard 启动指引
- 下载控制台:
bash
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
- 启动:
bash
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
- 客户端参数(Java 示例):
bash
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dcsp.sentinel.api.port=8719 \
-Dproject.name=demo-service
- 登录控制台(默认账号密码均为
sentinel),在界面中创建流控/熔断/系统保护规则并实时下发。
制定自己的防护“作战图”
- 观测指标:QPS、平均响应时间、错误率、下游依赖健康度。
- 阈值设定:基于容量评估与压测数据;对不同接口设置差异化规则。
- 熔断恢复:配置 Half-Open 探测逻辑,确保服务恢复后能自动合闸。
- 降级文案:提前与产品/前端确认兜底页面和提示语。
- 回溯复盘:每次限流 / 熔断触发后记录原因、调整阈值或扩容。
sequenceDiagram
participant User
participant Gateway as API 网关
participant Service as 核心服务
participant Fallback as 降级/缓存
User->>Gateway: 请求下单
Gateway->>Service: 令牌校验
alt QPS 超限
Gateway-->>User: 429 拥堵提示
else 调用异常
Service-->>Gateway: 熔断触发
Gateway->>Fallback: 查询兜底方案
Fallback-->>User: 排队中,请稍后
end
快速复习清单
- 限流把入口流量控制在系统承载范围内,优先保护核心能力。
- 熔断在依赖异常时主动切断调用,让系统尽快“回血”。
- 降级是兜底方案,让用户即使在故障时也感知到服务“还活着”。
- Sentinel 覆盖限流、熔断、降级和系统保护,控制台可视化配置与实时监控。
- 提前准备阈值、文案、监控与演练,才能在真正的雪崩到来前“精神焕发”地应对。
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://joyjs.cn/archives/4788