用 journalctl 三步定位 systemd 服务起不来
很多服务在 Linux 上用 systemd 托管。systemctl start 失败时,只看 “Job failed” 不够,真正的原因几乎都在 journal 里。本文用一个假设的 demo-api.service 走完排查,不依赖具体云厂商。
先确认单元状态
执行 systemctl status demo-api.service --no-pager -l。关注三行:Active、Main PID、Process。如果是 failed (Result: exit-code),说明主进程自己退出;如果是 Result: timeout,多半是 Type=notify 却没有 sd_notify,或者启动脚本卡住。status 只保留最后几行,完整日志还得看 journal。
按单元过滤 journal
journalctl -u demo-api.service -b --no-pager -n 80。参数 -b 只看本次开机,避免被昨天的日志带偏。-n 80 先看尾部。若要跟着重启,用 journalctl -u demo-api.service -f,另开终端执行 systemctl restart demo-api.service。失败瞬间的 traceback、配置路径、端口占用都会打在这里。
三个高频原因
端口已被占用。日志里常见 Address already in use。用 ss -tlnp 过滤端口,看谁占着,再决定改服务端口还是停掉旧进程。不要一上来就 kill -9,先确认不是同一个服务的残留子进程。
工作目录或配置文件不存在。WorkingDirectory 指向的路径没创建,或者 EnvironmentFile 权限是 600 且属主不是服务用户,systemd 会在 exec 之前直接失败,应用日志一行都没有。这时 journal 里会有 Failed to load environment files。用 systemd-analyze verify demo-api.service 可以在重启前查出语法和路径问题。
用户无权读文件。User=demo 时,家目录如果是 700 且属主是 root,进程能起来但读不到配置。把配置放到 /etc/demo-api/,目录 755、文件 640,用户组设成服务用户,比放在 root 家目录下稳妥。
留下可复查的记录
排障结束后把关键命令写进单元注释或仓库 README,而不是只留在终端历史里。Service 段建议写明 WorkingDirectory、EnvironmentFile 和 ExecStart,并加上 Restart=on-failure 与 RestartSec=3。再配合 StartLimitIntervalSec=60 和 StartLimitBurst=5,可以避免崩溃循环把磁盘日志打满。
小结
顺序固定为:systemctl status 看结果码,journalctl -u 看本次开机的尾部,再用 ss 和 systemd-analyze verify 验证端口与单元文件。这三步覆盖端口冲突、环境文件和权限三类最常见故障,比反复重启有效得多。
- 点赞
- 收藏
- 关注作者
评论(0)