微服务系统中,一个请求可能经过网关和多个业务服务。流量突然增加、下游持续变慢或依赖暂时不可用时,问题可能沿调用链扩大。
Sentinel 提供限流、熔断和降级等流量治理能力,但这些词经常被混在一起。规则配置成功不代表保护已经有效,更不代表系统自动具备高可用能力。
限流解决流量过多
限流关注的是单位时间内允许多少请求进入某个资源。
请求到达
-> 统计当前流量
-> 未超过规则:继续执行
-> 超过规则:拒绝、排队或采用指定策略可以按 QPS、并发线程数等维度限制。网关可以限制入口路由,业务服务也可以保护关键方法。
限流阈值不能随意复制。需要结合:
- 服务实例数量;
- 接口平均耗时;
- 线程和连接资源;
- 数据库与下游容量;
- 请求是否可排队;
- 超限后的用户体验。
阈值太高没有保护作用,太低会拒绝正常流量。
熔断解决持续失败或变慢
熔断关注下游调用的异常比例、慢调用比例或其他统计。当一段时间内持续异常时,暂时停止继续调用,给下游恢复机会。
调用下游
-> 统计慢调用或异常
-> 达到熔断条件
-> 一段时间内快速失败
-> 进入探测阶段
-> 根据探测结果恢复或继续熔断熔断不是永久关闭服务,也不是重启下游。它是在调用方减少无意义等待和故障扩散。
需要配置并验证:
- 统计窗口;
- 最小请求数;
- 慢调用阈值;
- 异常比例;
- 熔断时长;
- 恢复探测方式。
请求量很小时,只看异常比例可能产生误判,因此最小请求数很重要。
降级解决“失败时返回什么”
限流或熔断发生后,系统需要决定怎样响应,这就是降级策略的一部分。
降级可以是:
- 返回明确的服务繁忙提示;
- 返回缓存中的可接受旧数据;
- 返回空列表或默认内容;
- 跳过非核心步骤;
- 记录稍后重试的任务;
- 禁用某个次要功能入口。
降级结果必须符合业务语义。不能为了接口返回成功而伪造数据,也不能把写操作失败包装成已经完成。
隔离限制故障影响范围
线程池、信号量或服务实例隔离,可以避免某类请求占满所有资源。
例如视频处理、推荐查询和普通详情请求的资源特征不同。如果全部共享同一线程或连接资源,一个耗时任务可能拖慢其他接口。
Sentinel 的线程数规则可以限制并发,但完整隔离还可能涉及:
- 独立线程池;
- 独立服务或实例;
- 不同连接池;
- 队列容量;
- 容器资源限制。
限流和隔离可以配合,但不是同一个概念。
网关限流和服务限流的区别
网关限流发生在外部请求进入系统时,适合按路由、用户或客户端控制整体入口。
服务限流更靠近资源,可以保护某个业务接口或依赖。
外部请求
-> 网关限流
-> 业务服务限流
-> 下游调用熔断
-> 降级响应如果只有网关限流,内部服务间调用仍可能产生压力;如果只在服务限流,大量无效流量已经进入系统。两层规则需要职责清楚,避免重复拒绝和难以解释的阈值。
一个通用资源示例
@SentinelResource(
value = "queryVideoDetail",
blockHandler = "handleBlocked",
fallback = "handleFailure"
)
public VideoDetail queryVideoDetail(Long id) {
return loadVideoDetail(id);
}这是简化示例,不对应 HAOVP 的真实资源名、方法和降级实现。
blockHandler处理被 Sentinel 规则阻止的请求;fallback处理业务执行中的异常;- 两者不能混为同一种错误。
降级方法的参数和返回类型也要与原方法兼容。
规则放在哪里
规则可以在代码中初始化,也可以通过配置中心或 Sentinel 控制台管理。
动态规则更便于调整,但要考虑:
- 服务重启后规则是否保留;
- 多实例是否收到一致规则;
- 配置变更是否有版本和审计;
- 错误阈值能否快速回滚;
- 开发、测试和部署环境是否隔离;
- 控制台是否仅用于管理而非持久化来源。
规则来源不明确时,容易出现控制台看到了规则,重启后却消失。
不同接口不能用同一个阈值
查询详情、搜索、上传、登录和管理操作的成本不同。用同一个 QPS 阈值无法反映真实容量。
我会先收集:
- 平均和高分位耗时;
- 并发下线程占用;
- 数据库连接和慢查询;
- 下游依赖耗时;
- 单实例资源使用;
- 错误率与超时率。
没有这些信息时,阈值只能作为初始实验值,不能写成系统容量结论。
限流后的 HTTP 与业务响应
被限流时可以返回明确状态和业务错误码,让客户端知道是暂时繁忙,而不是认证失败或参数错误。
{
"code": "TOO_MANY_REQUESTS",
"message": "Please retry later",
"requestId": "example-request-id"
}示例不包含真实响应码和请求标识。
客户端是否自动重试要谨慎。大量客户端立即重试可能进一步放大流量,应结合退避、随机抖动和请求幂等性。
降级不能破坏数据正确性
查询接口可以考虑缓存或默认结果,写操作则更谨慎。
例如:
- 推荐服务不可用时,可以退回热门列表;
- 用户扩展信息失败时,可以在不影响核心内容的情况下省略;
- 评论创建失败时,不能返回“创建成功”;
- 视频状态更新失败时,不能只更新前端显示。
降级优先保护核心流程和真实状态,而不是保证所有接口都返回成功。
怎样验证规则真的生效
建立可重复的正常基线
-> 施加受控流量或故障
-> 观察规则是否触发
-> 检查响应与日志
-> 确认下游资源是否得到保护
-> 流量恢复后检查是否正常恢复需要验证的场景包括:
- 达到 QPS 或并发阈值;
- 下游持续慢调用;
- 下游连续异常;
- 半开探测成功和失败;
- 多实例规则一致;
- 降级结果符合业务语义;
- 规则修改和回滚。
只看到控制台中的规则条目,不能证明保护链路生效。
Sentinel 的边界
Sentinel 可以帮助流量治理,但不能替代:
- 数据库索引和查询优化;
- 业务幂等和事务;
- 消息可靠性;
- 容器资源限制;
- 多节点部署;
- 监控告警;
- 容量评估;
- 根因修复。
如果下游一直失败,熔断只能减少影响,不能让故障自行消失。
Sentinel 限流、熔断与降级的边界可以这样理解:限流控制进入多少流量,熔断决定何时暂停失败调用,降级决定受保护时返回什么,隔离限制故障占用多少资源。规则只有经过受控流量、依赖异常和恢复场景验证,才能说明它在当前系统中真正发挥作用。