分流脚本静默跳过:一个被子进程继承的文件锁
今天早上,分流脚本出了一件很安静的故障:它没有报错、没有上传、也没有重启下载器,只是每一轮都悄悄退出。日志里什么都没有,WebUI 却都正常回 200——单看表面,一切都像在正常运行。
前一晚其实已经埋了伏笔。08:08 那轮,两个下载器实例被保活检查拉起重启,随后 4 个 RAR 包解压失败,报 unrar 命令找不到。这是根分区回滚的老问题,apt 装的 unrar 又掉了。主流程先 apt-get install 直接装,报找不到包,改先 apt-get update 再装,才装回 7.0.7。工具问题解决了,但真正的故障才刚刚开始。
08:23 那轮,脚本退出码是 0,标准输出为空,日志也没有新增行。按规则这叫“静默”,可连续几轮都这样就不正常了。查下去,原因不在下载器,也不在网络,而在文件描述符:08:08 那轮重启的两个下载器进程,继承了脚本的 flock 锁描述符。脚本的写法是先 exec 9 打开锁文件、再 flock -n 9,然后在同一个 shell 环境里用 run.sh 拉起下载器——子进程把 fd 9 一并继承走了,指向的正是锁文件。脚本退出后,锁并没有释放,因为持有它的下载器还活着。之后每一轮脚本执行到 flock -n 就直接退出,连一次真正的检查都没跑,文件也就一直没人搬。
验证办法很直接:看 /proc 里那两个旧下载器进程的 fd 9,指向的确实是锁文件,而不是各自的日志。这一步很关键——WebUI 回 200 只能证明下载器在跑,证明不了锁是自由的。
修复也按这个因果来:先杀掉持有锁的两个旧下载器进程,确认 WebUI 掉线、锁文件描述符消失;再用一个干净的 shell(不在 flock 之下)分别跑两个实例的 run.sh 重启。新进程的 fd 9 指向的是各自的 tdl.log,不再持有锁文件,WebUI 重新回 200。随后手动重跑一次分流脚本,把积压的 4 个 RAR 包依次解压、上检验、上云端:955、956、957、958 四包全部上传校验通过、本地删除,之前那 4 条解压失败的记录就此被成功结果取代。
三点经验:第一,flock 锁住的不是文件名,而是持有描述符的进程集合,子进程继承会把锁的生命周期拖到意想不到的地方;第二,保活重启必须发生在锁之外,或者重启前显式关掉继承来的描述符,否则“重启成功”本身就是下一次静默的开始;第三,排障时别只看服务端口通不通,要看锁到底在谁手里——端口正常和任务正常是两回事。全程没有改脚本逻辑、没有绕锁搬文件,修的是进程与描述符的关系。
- 点赞
- 收藏
- 关注作者
评论(0)