用 systemd 给 Linux 程序做开机自启和崩溃自动重启(入门实践)
【摘要】 介绍如何用 systemd 编写 unit 文件,实现 Linux 程序开机自启与崩溃自动重启,并附常用命令与排错清单。
为什么用 systemd,而不是 nohup 或 rc.local
很多人部署小程序时习惯 nohup ./myapp &,或者写进 rc.local。问题是:nohup 进程崩溃后没人拉起,终端、会话异常还可能被误杀;rc.local 只管开机执行一次,没有依赖顺序、没有日志管理,新发行版甚至默认不启用。systemd 是现代 Linux 的标准服务管理器,原生支持开机自启、崩溃自动重启、依赖顺序、资源限制和统一日志,几行配置就能解决上述问题。
编写 unit 文件
假设程序放在 /opt/myapp/myapp,新建 /etc/systemd/system/myapp.service:
[Unit]
Description=My App Service
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
EnvironmentFile=-/etc/myapp/myapp.env
ExecStart=/opt/myapp/myapp --port 8080
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
要点:Restart=on-failure 表示进程非正常退出时才重启;RestartSec=5 让它等待 5 秒再拉起,避免疯狂重启;User 建议使用普通用户,不要图方便直接用 root;WantedBy=multi-user.target 决定了开机自启。
常用命令
sudo systemctl daemon-reload # 修改 unit 后必须执行
sudo systemctl enable --now myapp # 设置开机自启并立即启动
systemctl status myapp # 查看运行状态
sudo journalctl -u myapp -f # 实时查看日志
sudo systemctl restart myapp # 重启服务
验证崩溃重启:用 kill -9 杀掉主进程,几秒后再看 status,会发现 PID 已变化,服务被自动拉起。
常见问题排查
- 权限问题:User 指定的用户必须对可执行文件、工作目录和日志目录有权限,否则状态会显示 Permission denied 或 status=203/EXEC。
- 必须使用绝对路径:ExecStart 中的程序要写绝对路径,systemd 不会读取你登录 shell 的 PATH 和别名。
- 环境变量:服务里没有 .bashrc 的环境变量,请用 Environment= 或 EnvironmentFile= 显式声明,每行一个 KEY=VALUE。
- 改完不生效:忘记 daemon-reload 是最常见的原因。
- 反复启动失败:systemd 默认有启动频率限制,可用 journalctl -u myapp -e 查看原因,修复后执行 systemctl reset-failed myapp。
总结
用 systemd 管理程序,只需一个 unit 文件加几条 systemctl 命令,就能实现开机自启、崩溃自动重启和统一日志查看,比 nohup 和 rc.local 稳定、规范得多。建议所有长期运行的小服务都迁移到 systemd 上。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)