【读书活动感悟分享】《SRE Google运维解密》第17章 测试可靠性_文章

【读书活动感悟分享】《SRE Google运维解密》第17章 测试可靠性

张玉繁
发表于 2025-11-11 19:02:46

第17章 测试可靠性

1、测试的目的

测试:是一个用来证明变更前后系统的某些领域相等性的手段。每个在变更前后都能通过的测试降低了分析系统可靠性变化中的不确定性。完善的测试可以提供足够的细节信息,以帮助我们有效地预测某个系统未来的可靠度。

测试和平均修复时间的关系:

系统通过某项测试或者一系列测试并不一定能证明系统是稳定的,但是失败的测试通常证明了系统不稳定。

MTBF(Mean Time Between Failures,平均无故障时间):

指系统两次故障之间的平均间隔时间,数值越高,系统可靠性越强(比如 MTBF 从 10 天升到 30 天,说明生产故障更少、间隔更长)。

MTTR(Mean Time To Repair,平均修复时间):

指系统出现故障后,从发现到修复的平均时间,数值越低,故障恢复越快(比如 MTTR 从 2 小时降到 30 分钟,说明故障处理效率更高)。

随着测试的优化,可以带来的长期收益与短期的波动,长期收益是测试优化导致MTBF 上升,系统可靠性提高,故障发生率降低;短期波动是MTBF 上升能够让开发者可以更快迭代,但是快速迭代新功能可能会引发新的Bug产生从而导致发布速率暂时下降。这是“长期可靠性”与“短期迭代速度”的正常平衡 —— 测试优化的最终目标是让“快速迭代”和“高可靠性”共存,短期因修 Bug 降速是为了长期更稳定地快迭代。

2、软件测试的类型

软件测试基本分为两大类:传统测试和生产测试。传统测试主要用来在开发过程中离线评估软件的正确性。生产测试在生产Web服务器上进行,用来评估一个已经部署的软件系统工作是否正常。


传统测试:

(1) 单元测试:是最小、最简单的软件测试形式。这些测试用来评估某一个独立的软件单元,比如一个类或者一个函数的正确性。对SRE而言,单元测试覆盖越全,生产中“低级错误”“参数校验缺失” 等故障越少。

(2) 集成测试:通过独立的单元测试的软件组件被组装成大的系统组件。工程师通过在这个组件中运行 一个集成测试来检验该组件的功能的正确性。

(3) 系统测试:是一个在未部署的系统上运行的大型测试。某个组件的所有模块都会被装载到系统中。系统测试包括冒烟测试、性能测试、回归测试。


生产测试:

生产测试聚焦 “生产环境的真实性验证”,因为开发测试环境无法复现生产的流量、依赖、配置差异,所以生产测试对运行一个可靠的生产环境来说是必要的。

  • 配置测试:

    SRE 踩过最多的坑就是 “配置漏更”—— 开发改了配置没同步到生产,或灰度时某集群漏更配置,导致生产故障。SRE必须推动“配置测试自动化”。

  • 压力测试:

    通过压力测试我们能够更好的了解服务的性能瓶颈:

    数据库容量满到什么程度,才会导致写请求失败。

    向某应用每秒发送多少个请求,将导致应用过载并导致请求处理失败。

  • 金丝雀测试:
  • “金丝雀”一词来源于“煤矿中的金丝雀”这样一个说法,指代利用一只鸟来检测有毒气体以避免人类中毒的做法。主要是提醒我们在发布的时候需要进行测试性发布,分阶段灰度发布而并非全量,若灰度中出现错误,立即停止发布。(单个节点发布验证)

    3、创造一个构建和测试环境

    3.1 确定测试优先级

    SRE 很少从项目启动就参与,往往是项目推进一段时间后才加入 —— 此时项目的核心目标是 “验证原型可行性”,没人优先考虑“测试设计”,导致SRE 接手时“代码有原型,但测试一片空白”。遇到这种情况我们应该如何应对?

    优先测核心组件:比如计费系统(关联收入)、用户认证接口(影响登录)、支付回调(影响交易)。这些组件通常测试成本较低,且一旦出问题,运维压力会呈指数级增长。

    优先测外部依赖强的API:若我们维护的API出现问题,其他团队集成时可能因此引发一系列连锁反应,后续跨团队排查成本极高。

    发布前必跑基础冒烟测试:比如“服务能否启动”“关键接口是否返回200”“配置文件是否加载正确”。

    3.2 建立强测试文化

    建立强测试文化的一种方式是将所有遇到的问题都进行测试案例化。如果每个Bug都变成了一个测试用例,每个测试用例都应该在问题修复好之前处于失败状态。随着工程师修复好Bug,测试用例也一个一个通过,这样用不了多久就会有一套完善的回归测试体系。

    3.3搭建测试基础设施

    建立良好测试的软件的另外一项关键任务是建立起一套良好的测试基础设施。测试基础设施的基础是一套版本化源代码控制体系,可以追踪源代码的每一个改变。主要涉及三个模块:

    版本控制:所有代码(含测试代码、配置文件)纳入TFS、Git,确保“测试版本与生产版本可追溯”,避免“测试用的是旧配置,生产用的是新配置”的矛盾。

    持续构建系统:用Bazel、Jenkins等工具,每次代码提交后自动构建+执行测试,实时通知提交者结果。若测试失败,提交者必须优先修复。

    测试覆盖度工具:通过工具可以更好的聚焦测试,可以帮助量化和可视化测试覆盖程度。

    4、生产环境探针

    生产环境的探针本质是:在生产环境中,通过重放“已知特征的请求”,实时验证系统是否符合预期行为的测试手段。它不同于开发环境的单元测试/集成测试,而是直接在真实生产环境中运行,聚焦“开发环境无复现的真实场景”,在生产环境部署“探针测试”,核心是这3类请求:

    • 已知的错误请求(如参数异常的API调用):测系统是否正确返回错误码,不崩溃;
    • 可重放的正确请求(如用户登录、商品查询的标准请求):测系统是否返回预期结果,延迟、错误率是否达标;
    • 不可重放的正确请求(如支付、下单):用“影子流量”转发到测试环境,避免影响真实用户。

    这些探针的独特价值是:测试“前端+真实后端”的组合场景——比如前端更新后,后端未同步兼容,开发环境测试可能没问题,但生产探针能立即发现“接口返回格式不匹配”“空引用”等问题,通过探针从而能够更快速的发现问题,最大限度降低影响。

    总结感想:
  • 测试目标不是找Bug,是拦“0 MTTR Bug”(发布前拦截故障,避免生产救火);
  • SRE测试重点不是单元测试、集成测试,而是做“生产测试”(配置校验、灰度验证、生产探针);
  • 生产探针是“最后防线”:开发环境模拟不了的依赖/配置问题,靠生产环境探针发现;
  • 测试要嵌入流程:与发布绑定(发布前→灰度中→全量后),形成系统化的测试流程。
  •          对SRE来说,最好的运维不是“能快速解决故障”,而是“能让故障不发生”。测试不是成本,而是 SRE 最高效的 “可靠性杠杆”, 用少量的测试投入,换取生产故障的大幅减少、运维效率的显著提升、业务迭代的持续顺畅。SRE工程师不仅要在开发阶段做好代码审查、严格把控编码质量,更应该深入测试,把可靠性要求嵌入测试全流程,通过精准测试提前堵死故障漏洞,从源头避免生产问题。




    78 0

    评论
    

    意见反馈