服务依赖如何分级治理?
简化版
依赖分级不是按团队或服务大小排名,而是按“依赖失败对当前业务目标的影响”划分强依赖、可降级依赖和异步依赖。 每一级绑定不同的超时、重试、隔离、降级和告警策略,并按具体调用场景管理;同一个服务在下单链路和运营报表里可能是不同等级。
详细版
梳理入口到结果的调用图,为每条边记录业务影响、可接受陈旧度、失败处理、目标延迟和负责人。强依赖失败时应明确失败或进入可查询的处理中状态;可降级依赖返回经评审的缓存/默认结果;异步依赖写可靠事件后由后台收敛。
治理策略必须与剩余 deadline 和资源预算匹配。用户请求预算 500ms 时,不能给三个串行依赖各配 400ms 超时。分级结果进入配置、看板、演练和发布评审,并随业务变化复查,不能停留在文档标签。
完整版教学
一、为什么要给“调用边”分级
一个服务往往同时支撑交易、推荐和离线任务。把整个会员服务固定标成“核心”会导致所有调用都获得昂贵保护,也无法说明它失败时各业务该怎么办。真正需要分级的是 调用方场景 -> 被调用能力 这条边,因为影响取决于入口目标。
记忆钩子:依赖等级回答的是“这次调用失败后,当前业务还能不能给出诚实结果”。
二、三类依赖的语义
| 类型 | 失败影响 | 常见处理 | 示例 |
|---|---|---|---|
| 强依赖 | 核心结果无法成立 | 快速明确失败、隔离保护 | 支付确认依赖账务入账 |
| 可降级依赖 | 体验下降但主结果成立 | 缓存、默认值、裁剪字段 | 商品页的推荐列表 |
| 异步依赖 | 可稍后完成 | 可靠事件、重试、对账 | 下单后的积分发放 |
“异步”不等于不重要,资金对账也可异步但必须可靠;“强依赖”也不等于无限等待,越核心越要控制 deadline,避免结果未知。
三、从业务影响做判定
评审时依次问:没有它能否完成承诺?能否用旧数据?可以延迟多久?失败是否产生资金或合规风险?是否有人工补救?这些答案比“这个服务有几个 9”更有用。依赖自己的 SLA 很高,也可能因为调用语义不可替代而是强依赖。
下单
├─ 库存预占:强依赖
├─ 优惠核销:强依赖(使用优惠时)
├─ 推荐打标:可降级
└─ 积分发放:异步依赖
四、deadline 预算要可加总
假设入口 P99 目标 600ms,网关与本地处理预留 100ms,剩余 500ms。两个串行强依赖不能各超时 500ms;可以分配库存 180ms、价格 150ms,并给重试与网络抖动留 170ms。并行调用的关键路径取最大值,但仍会共同占用连接和线程。
入口预算 = 600ms
本地/网关 = 100ms
依赖预算 = 500ms
库存 180ms + 价格 150ms + 余量 170ms = 500ms
五、等级怎样映射到治理规则
强依赖通常使用独立舱壁、短超时、谨慎重试和高优先级告警;可降级依赖配置熔断与业务 fallback;异步依赖关注消息持久化、幂等消费、积压和最大完成时间。策略并非等级越高重试越多,强依赖故障时无节制重试反而更容易拖垮核心链路。
例如峰值 2000 QPS 时推荐依赖预算只有 500 QPS,降级应在入口裁掉 1500 QPS,而不是让其进入线程池后超时。等级必须转换为可执行配置,才有治理价值。
六、依赖图、变更和演练
通过 Trace 建调用图只能发现实际发生过的同步调用,动态分支、低频任务和消息链路还需代码与架构清单补全。每条边至少记录 owner、等级、超时、fallback、数据新鲜度和最近演练时间。新增强依赖应进入架构评审,因为它会降低整条链路可用性。
演练可分别注入超时、错误、陈旧数据和消息积压,检查系统是否按等级行动。监控则展示各等级流量、失败、降级命中和预算耗尽,避免大量“可降级”依赖实际上没有 fallback。
七、常见误区与追问
- 误区:核心团队维护的服务都是强依赖。 等级由具体业务影响决定,不由组织归属决定。
- 误区:异步依赖失败可以不管。 仍需持久化、重试、对账和最大收敛时间。
- 误区:强依赖应该配置更长超时。 长等待会耗尽入口预算并放大资源占用。
- 误区:调用图自动生成后分级就完成了。 Trace 看不到未触发分支,也无法判断业务语义。
- 追问:同一依赖能有多个等级吗? 可以,必须按接口、调用场景乃至业务条件标注。
- 追问:如何衡量分级有效? 看故障演练时核心成功率、降级命中、预算超时和故障半径是否符合预期。
- 追问:等级多久复查? 重大业务变更、依赖新增后立即复查,并设周期性 owner 确认。
八、加强记忆
依赖分级按“边”不按“点”,按业务承诺不按服务名。先判定失败后能否继续,再把强依赖、可降级依赖、异步依赖分别映射到 deadline、隔离、fallback 和补偿,最后用调用图维护、变更评审与故障演练保持分类真实有效。