用 Node 的 fs.watch 监听配置变更,我遇到了重复事件
线上有个服务需要热加载本地 JSON 配置,Node 18.17,Linux 容器,配置大概 200 行,一天改两三次。最初用 fs.watch 监听文件,改了配置后偶尔会连续触发两次回调,导致重载逻辑跑两遍,其中一次读到写了一半的文件直接 JSON.parse 报错。
我的做法是把 watch 包一层防抖,并且重载时先读进内存再解析,失败就保留旧配置。关键片段:
const fs = require('fs');
let timer = null;
let current = loadConfig();
function loadConfig() {
const raw = fs.readFileSync(configPath, 'utf8');
return JSON.parse(raw);
}
function reload() {
try {
current = loadConfig();
console.log('config reloaded');
} catch (e) {
console.error('config reload failed, keep old', e.message);
}
}
fs.watch(configPath, (eventType) => {
if (eventType !== 'change') return;
clearTimeout(timer);
timer = setTimeout(reload, 100);
});
为什么是 100ms:编辑器保存文件通常先 truncate 再 write,fs.watch 在 Linux 上底层是 inotify,可能上报多次 IN_MODIFY,防抖窗口太短没合并,太长又感觉重载慢。100ms 是试出来的,没有理论保证。另外 reload 里先读再解析,解析失败不覆盖 current,这样即使防抖没兜住,也不会把服务搞挂。代价是配置写坏时不会自动恢复,得人工再改一次。
哪里会失效:fs.watch 在 Docker bind mount 和 NFS 上行为不一致,有的环境根本不触发;文件被 mv 替换时 inotify 监视的是旧 inode,改名后可能收不到事件。我自己踩过用 vim 保存后监听失效,后来改成监听目录而不是文件,过滤出目标文件名,才稳定些。但监听目录在文件多的时候事件噪音大,需要自己权衡。
你们在生产环境用 fs.watch 还是 chokidar?有没有在容器里遇到过监听直接静默的情况?
0
赞同度 100% · 0 条评论 · 4 阅读
0 条评论
还没有评论,写下第一条。