现场是这样的。CentOS 7 上升级到 systemd 219 之后,一个 PHP 队列进程每天凌晨挂掉,日志里是连接不上 /tmp/queue.sock,重启就恢复,第二天同样时间再挂。
中间走过弯路,把「tmpfs 挂载的 /tmp 重启即空,服务启动顺序又排在写入 socket 之前」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。systemd-tmpfiles 按默认规则清理 /tmp 下十天未访问的文件,socket 文件的访问时间不会刷新;tmp.conf 里配置了按类型批量删除,socket 一类也在清理范围内;私有 tmp 目录被 ProtectSystem 或 PrivateTmp 改动,进程看到的路径与清理路径不是同一个。
动手时先确认 socket 是被删掉还是被改名
ls -l /tmp/queue.sock && ls -ld /tmp
随后查 tmpfiles 的实际清理规则
systemd-tmpfiles --cat-config | grep -A5 '/tmp'
接着把业务 socket 目录排除在清理之外
printf 'x /tmp/queue.sock\n' > /etc/tmpfiles.d/keep-queue.conf
末了把 socket 迁到不会被清理的目录并重启服务
mkdir -p /run/queue && sed -i 's#/tmp/queue.sock#/run/queue/queue.sock#' /etc/queue.conf && systemctl restart queue
怎么算真的好了,看的是同一批现象。隔天同一时间服务仍在运行,/run/queue/queue.sock 存在且属主正确,journalctl 中连续三天没有连接失败的记录。
这里还有个坑。/tmp 最适合放随时可丢的临时文件,长期存在的 socket 应该放 /run;改路径时客户端和服务端要同步,否则会连到旧文件上。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
