这类问题我又碰上了一次。CentOS 7.9 上把原来 nohup 启动的 jar 包改成 systemd 管理,ExecStart 直接照抄了 shell 命令末尾的 &,systemctl start 之后服务立刻 inactive (dead),status 显示 code=exited status=0,java 进程根本没留下。
第一反应是「程序自己 fork 到后台,前台进程直接返回」,验证下来不成立。
排查方向其实有限,先把可能性排一排。ExecStart 末尾的 & 被当成参数传给程序,systemd 不经过 shell 解析;Type=simple 下主进程退出就认为服务已经结束;没有设 RemainAfterExit,退出后 unit 马上变成 inactive。
第一件事是看 unit 的实际退出状态
systemctl status app --no-pager -l
去掉 & 让进程在前台运行
grep -n ExecStart /etc/systemd/system/app.service
接着确实要后台化就用 forking 并配 PIDFile
printf 'Type=forking\nPIDFile=/run/app.pid\n' >> /etc/systemd/system/app.service
剩下的就是重载后确认进程还在
systemctl daemon-reload && systemctl restart app && pgrep -af 'java -jar'
隔了一天再看,现象没变,说明不是偶发。
那几天正好在做别的变更,先把时间线对齐才敢动手。
恢复的判定其实很直接。服务状态 active (running),java 进程 PID 稳定,重启机器后也能自动拉起。
提醒一点。systemd 不经过 shell,管道、重定向、&& 都不会生效,复杂启动逻辑应该包一层脚本。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
