本文翻译自上述Oreilly出版的电子书《Distributed systems Observability》(By Cindy Sridharan)第三章。
传统意义上,测试被视为生产环境前或发布前的专属活动。部分企业至今仍保留专职测试团队或质量保障(QA)工程师,对开发团队构建的软件进行人工或自动化测试。软件一旦通过QA验收,便会移交运维团队运行(针对服务类产品)或作为正式版本发布(针对桌面软件或游戏)。
这种模式正逐步被淘汰(至少对服务类产品而言)。如今开发团队需要同时承担自身所开发服务的测试与运维职责。这种新模式具有革命性意义——它使开发团队能够以务实且可持续的方式,全面考量测试的范围、目标、权衡与收益。要构建理解服务运行机制的整体策略,并在生产环境问题暴露前验证其正确性,关键在于根据服务的可用性、可靠性与正确性需求,精准选择测试技术组合。
软件开发人员已习惯将生产环境视为不可触碰的圣域,即便这意味着他们永远只能在高度模拟的环境中进行验证。保持测试环境与生产环境高度一致确实能带来类似彩排的效果,但这终究无法替代真实场景下的演出。
预生产测试是软件工程师从入行起就根深蒂固的理念。对实时流量进行实验的做法,要么被视为运维工程师的特权,要么会引发恐慌。要将部分回归测试转移到生产环境监控中,不仅需要思维模式的转变和风险承受意愿,更重要的是系统设计的全面革新,以及对发布工程实践与工具的持续投入。
换言之,这要求我们不仅要为故障设计架构,更要将编码与测试的默认目标从"确保成功"转变为"应对失败"。
为故障而编码
为故障编码意味着承认系统终将失效,而调试能力至关重要。这需要从系统设计之初就内置可调试性,具体包含三个维度:
- 理解应用的运行时语义
- 理解依赖项的运行时特征
- 编写具备可调试性的代码
应用的运行时语义
聚焦应用运行时语义要求开发者与SRE共同考量:
- 服务的部署方式及工具链
- 服务绑定端口策略(动态端口0或固定端口)
- 信号处理机制
- 主机进程启动流程
- 服务注册发现机制
- 上游服务发现方式
- 服务终止时的连接排空策略
- 重启优雅度
- 配置加载方式(静态/动态)
- 并发模型(多线程/单线程事件驱动/actor模型/混合模式)
- 前端反向代理的连接处理架构(预fork/线程/进程)
虽然许多组织通过平台化工具将这些细节抽象化,但掌握这些基础概念能显著提升工程师的问题定位能力。
依赖项的运行时特征
我们构建在日益"渗漏"的抽象层之上,其故障模式往往未被充分认知。以下是近年实践中需要深入理解的典型特征:
- Consul客户端库的默认读取一致性模式(服务发现场景下强一致性未必理想)
- RPC客户端的缓存保证机制与默认TTL设置
- 官方Confluent Python Kafka客户端的线程模型及其在单线程Python服务中的影响
- pgbouncer默认连接池大小设置及连接复用策略(默认为LIFO)与Postgres部署拓扑的适配性
有时仅需调整某行配置或覆写库默认值,就能带来显著的可靠性提升。
可调试性代码
编写可调试代码意味着为未来问题排查预留空间,这要求:
- 掌握各类埋点方案(指标/日志/异常追踪/链路追踪或其组合)的优劣
- 根据服务需求与依赖项特性选择最佳埋点方案
- 这需要开发者直面挑战,在编码阶段就充分考虑可观测性需求。
测试的本质
必须认识到:
测试只是对系统正确性的最佳努力验证,以及对故障模式的最佳努力模拟。正如Dijkstra所言:“测试能有效证明缺陷存在,却永远无法证明缺陷不存在。”
单元测试仅验证系统在特定输入下的行为,且通常在高度受控(大量mock)环境中进行。模糊测试虽然能通过随机输入验证代码健壮性,但仅适用于单一服务。端到端测试虽能进行一定程度的全局验证,但复杂系统的故障模式往往更复杂——没有任何测试能预测所有潜在故障向量。
这并非否定测试价值。研究表明,在分布式系统中"测试错误处理代码可预防58%的灾难性故障"。生产环境可观测性工具的兴起,并不意味着预生产测试可以被取代。
但越来越明显的是,仅依赖预生产测试甚至难以覆盖系统的"已知未知"问题。有效的故障测试需要承认:某些故障模式只能在生产环境显现。
生产环境测试的艺术
“在生产环境测试"常被贴上鲁莽编程、测试不充分、漠视用户体验等负面标签。若实施不当,确实会坐实这些指责。生产环境测试绝非预生产测试的替代品,实施难度也远超想象。要安全有效地实施,需要:
- 严谨的方法论
- 对最佳实践的深刻理解
- 专为此类测试设计的系统架构
为构建安全有效的生产环境测试体系,需避免将其简单视作工具集合。完整的生产环境测试涵盖三个阶段的技术矩阵:部署阶段、发布阶段、发布后阶段(图3-1)。
生产环境测试的核心前提是:必须实时测量被测系统的表现,并能根据需要中止测试。这要求具备:
- 快速的系统行为反馈环
- 关键性能指标的监控能力
对HTTP服务而言,可能包括核心接口的错误率与延迟;对用户直面服务,还需监测用户参与度变化。本质上,生产环境测试就是主动"监控"正在进行的生产环境实验。
结语
生产环境测试看似高不可攀,但其目标并非消除所有系统故障。虽然实施过程充满挑战与风险,但严谨的执行能极大增强对复杂分布式系统可靠性的信心。这需要持续投入,但回报是值得的。
(注:由于篇幅限制,报告中关于生产环境测试的详细分类技术未展开论述,感兴趣的读者可参阅作者专题文章。)