Page 173 - 《软件学报》2026年第2期
P. 173
652 软件学报 2026 年第 37 卷第 2 期
依赖图, 其中节点代表服务, 边代表调用关系. 这个精炼后的依赖图将作为核心输入, 传递给后续的变更评分模块
进行更精细化的根因分析.
4.5 变更依赖关系构建
由于服务功能的快速迭代, 现代微服务架构中的单个服务可能会在极短时间窗口内 (如 48 h) 经历多次变更
部署. 这种高频变更特性使得故障诊断面临新的挑战: 当系统出现异常时, 运维团队不仅需要定位故障服务, 还需
要在众多变更中准确识别导致问题的具体变更版本. 在获得完整的服务依赖图后, 我们可以通过集成变更管理系
统 (如 GitOps 工具链或企业内部的变更单系统) 查询服务依赖图上所有服务在最近 H h 内发生的变更列表. 值得
注意的是, 一个服务的多次变更之间往往不是相互孤立的, 而是存在复杂的版本依赖关系链. 例如, 假设服务 A 的
变更 1 在 24 h 前开始部署, 并在 12 h 前完成; 随后, 服务 A 的变更 2 在变更 1 完成后立即开始部署. 这种情况下,
变更 2 在版本上直接依赖于变更 1 的基础代码状态. 如果最终发现是变更 1 引入了缺陷, 那么仅回滚到变更 2 之
前的版本并不能彻底解决问题, 因为变更 2 是基于已经存在缺陷的变更 1 版本进行的迭代. 此时, 必须回滚到变
更 1 之前的原始稳定版本, 系统才能完全恢复正常. 因此, 在分析故障时, 对同一个服务的多个变更, 必须首先通过
代码仓库的提交历史、构建流水线的依赖关系或部署系统的版本记录, 精确还原它们之间的版本依赖图谱.
为了获得同一个服务的多个版本之间的依赖关系, 需要建立系统化的版本溯源机制. 具体而言, 可以从以下 3
个维度进行依赖关系提取: (1) 代码仓库维度: 通过分析 Git 提交历史中的分支合并记录和 tag 标记, 确定各版本间
的代码继承关系; (2) 构建流水线维度: 检查 CI/CD 系统中各次构建的输入输出依赖, 特别是容器镜像的层级依赖
关系; (3) 部署配置维度: 比对 Kubernetes 等编排系统中的 Deployment 版本更迭记录, 识别滚动更新过程中的版本
替换顺序. 这 3 个维度的数据可以通过调用各系统的开放 API 进行自动化采集, 并存储为有向无环图 (DAG) 的形
式, 其中节点代表特定版本, 边代表版本间的依赖关系. 例如, 当服务 A 的 v1.2 版本是基于 v1.1 版本的代码构建,
而 v1.3 又依赖于 v1.2 时, 就会形成 v1.1→v1.2→v1.3 的依赖链. 这种显式的版本依赖图谱不仅可以帮助快速定位
需要回滚的目标版本, 还能在变更前进行影响评估, 预测某个变更可能波及的依赖服务范围. 在实际实现中, 可以
开发专门的版本依赖分析器, 定期从各子系统同步元数据, 并建立统一的版本依赖知识图谱, 为故障诊断提供更全
面的上下文信息.
4.6 根因变更推断
在完成服务依赖图的构建和变更依赖关系的分析后, 系统已经具备了完整的拓扑结构和变更上下文信息. 接
下来的核心挑战是从众多候选变更 (通常每个故障事件涉及上百个时空相关变更) 中准确定位最可能导致故障的
根因变更. 本文在根因变更推断中综合考虑了变更前后 KPI 差异、变更时间与故障时间的相关性和服务依赖强度
这 3 个关键维度的因素, 这些因素共同构成了一个多维评估框架.
4.6.1 KPI 差异得分计算
为了降低部署新软件版本所带来的风险, 灰度变更已经成为软件部署中一种流行的技术手段. 在灰度变更中,
工程师们首先只在一部分服务实例上部署软件变更, 而不是立即更新整个服务的所有实例. 这样做的好处在于, 如
果已变更的服务实例引发异常, 可以及时回滚. 如果没有出现异常, 就可以逐步将变更推广到属于该服务的所有实
例, 直到所有服务实例都完成更新.
大多数变更故障通常会在灰度变更过程中显现出来. 其典型表现是已变更服务实例组和未变更服务实例组之
间出现明显的性能或可靠性差异. 例如在图 6 中, 服务 A 上线了一个缺陷变更, 当前处于灰度变更过程中. A 1 和
A 2 是已变更服务实例, A 3 和 A 4 是未变更服务实例. 图中的曲线表示每个服务实例的请求延迟. 此次服务 A 的变
更引发系统延迟上升, 进而触发告警系统. 通过分析服务 A 中已变更服务实例组和未变更服务实例组之间的请求
延迟可以发现, 已变更的 A 1 和 A 2 的请求延迟剧烈上升, 而未变更的 A 3 和 A 4 的请求延迟保持稳定. 通过对比 A 1
和 A 2 与 A 3 和 A 4 可以发现只有已变更的服务实例出现异常, 因而可以推断异常是由 A 的缺陷变更导致的.
为了检测出已变更和未变更服务实例组之间是否出现显著的差异, 本文采用了一种分流思想 [36] 对比测试组
(已变更服务实例) 和对照组 (未变更服务实例) 的性能表现. 其核心思路是, 在灰度变更过程中, 如果一个故障是由

