用 journalctl 排查 Linux 服务为什么起不来
服务刚部署上去,systemctl start 返回失败时,终端里往往只剩两三行红字。单元文件稍复杂一点,真正的原因通常不在这三行里,而在 systemd 交给 journald 的完整日志中。journalctl 就是专门读这份日志的工具。这篇只讲日常排障会反复用到的几条命令,不展开 journald 的存储格式。
先确认服务单元的名字。自定义服务一般以 .service 结尾,例如 myapp.service。不确定时可以执行 systemctl list-units --type=service --state=failed,先把当前处于失败状态的单元列出来,避免在错误的名字上浪费时间。
最常用的一条是按单元过滤:journalctl -u myapp.service -n 200 --no-pager。-u 指定单元,-n 限制条数,--no-pager 让输出直接打在终端里,方便复制。如果服务在反复重启,加上 -b 可以只看本次开机之后的记录,避免被几天前的旧报错干扰。
时间窗口同样重要。--since "10 min ago" 或 --since "2026-11-03 14:00" 能把范围收窄到你刚刚操作的那一段。和 -u 一起用,日志会一下子干净很多。排障时建议先把窗口缩到最近一次启动,再往前扩,而不是一上来就把全部历史拉出来。
优先级用来抓真正的错误。-p err 只看 error 及以上,-p warning 会把警告也带上。很多启动失败其实是 warning 级别的配置被忽略,例如环境变量文件不存在、端口已被占用但进程仍尝试继续。先看 err,再放宽到 warning,通常就能定位。
还有一个容易漏掉的细节:有的进程不是被 systemd 直接拉起,而是由脚本再 fork 出去。此时 -u 只能看到 systemd 自己的记录。子进程如果没有把日志写回 journal,还需要对照应用自己的日志文件。可以用 journalctl -u myapp.service -o cat 只看消息正文,按时间戳去对业务日志。
实战时可以按这个顺序走。第一,systemctl status myapp.service 看退出码和最近几行。第二,journalctl -u myapp.service -b -n 200 --no-pager 看本次开机的完整上下文。第三,信息太多时加上 --since 和 -p warning 收窄。第四,确认 WorkingDirectory、User、EnvironmentFile 和 ExecStart 指向的路径在目标机器上真实存在,并且运行用户有权限。权限问题在日志里常常只表现为 Permission denied,或者 code=exited, status=203/EXEC。后者多半是可执行文件路径写错,或者缺少解释器。
最后记得日志本身也会滚动。默认 journald 可能只保留一定体积,过很久再查会发现记录已经不在。排障当下就把关键几十行复制下来,比事后再回忆可靠得多。把上面几条命令做成自己的小抄,下次服务起不来时,先读 journal,再改配置,会少走很多弯路。
- 点赞
- 收藏
- 关注作者
评论(0)