统计脚本和补偿任务都会更新 stats.json,每隔几分钟就有一次内容只剩半截,JSON.parse 报 Unexpected end of JSON input。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,writeFile 先截断再写入,两个进程同时进来,后写的会把前一个的内容盖掉。写入过程不是原子的,读取端拿到中间状态就解析失败。

「并发写文件」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。改完顺手把文档补一句,省得下次自己重新推一遍。

const fs = require('fs');
fs.writeFileSync('stats.json.tmp', JSON.stringify(data));
fs.renameSync('stats.json.tmp', 'stats.json');

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

具体做法是,先写临时文件 同目录下 rename 原子替换;跨进程用文件锁 或者干脆改成写数据库;读取端加一次重试 解析失败隔 100ms 再读;把两个任务的调度时间错开 这只能缓解 不能当方案。

最后用这个标准收尾,跑一整天 stats.json 没有再出现半截内容 解析失败的日志归零。

作者 9823189