Linux 服务起不来?用 systemctl + journalctl 按这 5 步排查
在 Linux 服务器上部署应用,最常见的故障不是代码写错,而是服务起不来:systemctl start 一回车就报 failed,或者启动后几秒就退出。别急着重装,先按下面 5 步定位,多数问题 10 分钟内就能找到原因。第一步:先看服务状态,别只看报错一行
执行 systemctl status <服务名> --no-pager,重点看三处:Loaded 行确认加载的是哪个 unit 文件,有没有拼错路径;Active 行确认是 failed 还是 activating 又退回 inactive;最后几行日志往往只截取了尾巴,不能当作全部证据。如果服务反复重启,还要看 Restart 计数,短时间内重启几十次通常是启动后立即崩溃,而不是配置没生效。第二步:用 journalctl 看完整日志
systemctl status 只显示尾部,完整日志用 journalctl -u <服务名> --since “10 minutes ago” --no-pager 查看。加上 -f 可以实时跟随输出,复现一次启动就能看到崩溃前的最后一行。如果怀疑是更早的问题,用 --since “1 hour ago” 或 -b(本次开机以来)扩大范围。注意把时间范围收窄,否则会被无关日志淹没。第三步:核对 unit 文件里的启动命令
执行 systemctl cat <服务名>,检查 ExecStart 指向的程序路径是否存在、参数是否正确、WorkingDirectory 是否存在、User 指定的用户是否存在。常见坑有三个:一是二进制文件换了路径但 unit 没改;二是相对路径,systemd 默认工作目录不是你的 shell 当前目录;三是环境变量没传,程序在 shell 里能跑、在 systemd 里跑不起来,往往就是缺了环境变量,这时可以在 unit 里用 Environment 或 EnvironmentFile 补齐。第四步:查端口、权限和依赖
如果日志里出现 Address already in use,说明端口被占用,用 ss -tlnp | grep <端口> 找到占用进程,确认是旧进程没退出还是两个服务撞了端口。如果是 Permission denied,检查文件属主、目录权限和 SELinux/AppArmor(可用 setenforce 0 临时验证,但生产环境不要长期关闭,应用好后再针对性放行)。如果服务依赖数据库或网络,先确认依赖服务本身已启动:systemctl is-active <依赖服务名>,并在 unit 里用 After 和 Requires/Wants 表达启动顺序,而不是靠 sleep 碰运气。第五步:手动复现一次
把 ExecStart 里的命令原样拿到 shell 里跑一遍(注意切换到 unit 里指定的 User 和 WorkingDirectory),很多在 systemd 下看似神秘的报错,手动一跑就现形:缺库、缺配置文件、配置文件格式错误、证书过期。手动能跑通、systemd 跑不通,问题就在 unit 本身;手动也跑不通,问题就在程序或环境,二者分界一清,排查就不再绕圈。最后提醒两点:一是每次改完 unit 文件都要执行 systemctl daemon-reload 再重启服务,否则改动不生效;二是修好后用 systemctl enable <服务名> 确认开机自启已打开,避免服务器一重启故障重演。排查时养成习惯:先看状态、再看完整日志、再核对 unit、再查端口权限依赖、最后手动复现,基本能覆盖绝大多数服务启动故障。
- 点赞
- 收藏
- 关注作者
评论(0)