知识卡片

用专项异常模拟工具覆盖常规测试的盲区:OpenResty的I/O与内存泄漏测试实践

普通读书笔记卡

内容

OpenResty整个项目一直践行测试驱动开发,每个功能点和历史Bug都配有完整测试用例,用Test::Nginx框架同时做白盒和黑盒测试,测试用例还会在代码层面做动态追踪,验证实际执行路径是否和预期一致。但更值得注意的是它针对两类”常规测试很难覆盖到”的场景专门开发了模拟工具:一是I/O异常场景,通过mockeagain组件主动模拟读EAGAIN、写EAGAIN、写超时这几种极端读写事件——这类异常在真实网络环境下发生的概率很低、很难在常规压测中稳定复现,但一旦线上真的撞上却往往是最难排查的边界Bug,专门模拟出来测试,能把这类原本要靠运气才能撞见的问题提前暴露;二是内存泄漏,Test::Nginx提供了leak checking测试模式,在这个模式下用ab、weighttp这类压测工具长时间高频访问接口,同时持续高频采样Nginx进程的内存占用,通过长时间运行下内存曲线的变化趋势来判断是否存在泄漏,而不是靠肉眼观察某次运行是否崩溃。这个实践提示了一条测试设计的通用原则:常规的功能测试和常规的压力测试,天然倾向于覆盖”正常路径”和”能被稳定复现的异常”,而真正难缠的线上问题往往藏在那些概率极低、条件苛刻的边界场景(网络层面的瞬时异常、缓慢累积的资源泄漏)——针对这类场景,与其被动等待它们在生产环境自然发生再去排查,不如主动构造专门的模拟工具,把这些低概率场景变成可以稳定复现、可以纳入日常测试流程的用例。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.11 OpenResty的现在和未来"节,"2.11.5 OpenResty中的测试和调试"(源文件:_epub-src/OEBPS/Text/Chapter2_11_6.xhtml) - 结论依据:原文说明"对于I/O操作的精确覆盖,会通过OpenResty的mockeagain组件来摸拟极端的读写事件,包括读EAGAIN、写EAGAIN和写超时这几种情况……对于内存泄漏的测试,Test::Nginx集成了……leak checking测试模式,在此模式下,会调用ab和weighttp工具长时间压力访问测试接口,同时高频采样NGINX进程的内存占用",直接支撑本卡片结论。 - 原始内容:对于I/O操作的精确覆盖,会通过OpenResty的mockeagain组件来摸拟极端的读写事件,包括读EAGAIN、写EAGAIN和写超时这几种情况……对于内存泄漏的测试,Test::Nginx集成了……leak checking测试模式,在此模式下,会调用ab和weighttp工具长时间压力访问测试接口,同时高频采样NGINX进程的内存占用。