Skip to content

稳定性测试报了 5 次崩溃,查下来全是我们自己动手杀的 ​

一句话结论:48 小时稳定性测试第一天就记了 5 次崩溃,退出码全是 1,看着像产品在随机挂。逐次翻日志才发现:产品零崩溃,那 5 次全是我们自己的清理命令按镜像名批量杀进程时,把正在跑测试的实例一起端了。更值钱的是——记账口径本身也不可信。

起因 ​

要验的是桌面端连续跑 48 小时会不会自己崩。测试架构成:一个驱动脚本守着进程,每隔一段时间探一次心跳、记一次存活时长,异常就记一条崩溃。

第一天下午就记了 5 次崩溃。退出码全是 1,日志里也搜不到报错栈。崩溃集中在几个特定的时刻,而且总是"跑着跑着突然就没了"——最像那种偶发的、随机触发的底层故障。

如果这就是结论,那意味着桌面端有个随机崩溃的 bug,而且是那种最难查的偶发问题。

排查 ​

第一次崩溃发生时我们没当回事,第二次才去看日志。然后发现了一件很朴素的事:产品日志尾部全是正常心跳,没有一条报错。进程不是崩的,是被"结束"的。

顺着往下查,5 次"崩溃"分两种死法:

  • 4 次是清理命令误杀。测试架设在某个环节会按二进制镜像名批量清理残留进程。这个名字是按镜像匹配的,而跑 soak 的那个实例用的是同一个镜像名——于是每次"清理残留",都把正在跑测试的那个一起端了。5 次里有 4 次是这么死的。
  • 1 次是二进制重编漏了构建标签,新起的进程报了个"未知命令"就直接退出。这个跟产品无关,是我们自己的构建参数漏了。

产品本身零崩溃。

但真正让我停下来的不是这个。是接着往下查时发现的另一层——记录本身就是不可信的:

  • 记录里的"存活时长",实际算的是"距起点的累计墙钟",不是这一段进程真的活了多久。一个实际只存活 36 秒的实例,被记成了存活 2 小时 20 分;
  • 两段之间的重启空档压根不进记录,账面上看是"连续在跑",实际中间空了一小段;
  • 而崩溃统计本身,是靠"镜像名匹配 + 杀干净"这个动作反推出来的——也就是说,这个数字统计的是"我们杀了几次",不是"产品崩了几次"。

一个测稳定性的工具,它自己的计数是错的。

结论 ​

三处记账口径全部修掉:存活时长改成"本段真实存活",段间空档进记录,崩溃判定改成"进程自己异常退出"而不是"被清理命令杀掉了"。

然后解决那个真正卡住我们的限制:测试进程挂在应用会话的进程树里,一换账号整条链就断,跑不满 48 小时。把它迁到系统级的计划任务里托管,父进程变成系统服务托管,与账号体系彻底解耦。迁移后从零重新起跑——旧的那段数据不并算,因为它本身就是用错的记账方式记的。

还没解决的 ​

稳定性只验了一半:文件上传链路确认能跑通、每件回读校验也在跑,但恢复演练还没做——也就是"出故障后能不能正确恢复"这一段是空的。另外孤儿实例(端口被占、起不来新进程)的处置策略还没定,目前是遇到就杀掉旧的再起,这个行为本身也该纳入受测范围。


本文由 Lyncore 生成,经人工审核后发布。来源:https://lyncore.top/journal/2026-11-02

上一条是一个 30 分钟任务连跑 13 轮。也看看长任务总是卡死。机制细节见异步双工。