讲解 systemd service 单元、运行用户、环境、启动自启、重启策略、journalctl 和常见退出状态。
默认顺序:先用计划中的普通运行用户手工启动应用,确认命令、工作目录和环境变量都正确,再在 /etc/systemd/system/ 创建服务单元。systemd 本身不收费,也不会自动删除数据;错误的 Restart=always 会造成重启循环和日志爆增,不要默认用 root 运行。

先确认应用可以手工运行
使用最终运行用户测试完整命令、配置、端口和文件权限。systemd 不会加载交互 Shell 的全部环境,依赖 .bashrc、相对路径或临时变量的命令容易失败。
创建服务单元
[Unit]
Description=Example API service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=app
Group=app
WorkingDirectory=/opt/example-api
EnvironmentFile=/etc/example-api.env
ExecStart=/opt/example-api/bin/server
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
[Install]
WantedBy=multi-user.target保存到 /etc/systemd/system/example-api.service。用户、路径和命令必须按项目调整;环境文件应限制权限。
加载、启动与自启
sudo systemctl daemon-reload
sudo systemctl start example-api
sudo systemctl status example-api --no-pager
sudo systemctl enable example-api
systemctl is-enabled example-apistart 是立即启动,enable 是建立开机启动关系。先验证运行正常,再启用自启。
查看日志与退出原因
sudo journalctl -u example-api -n 100 --no-pager
sudo journalctl -u example-api -f
systemctl show example-api -p ExecMainStatus -p Result常见原因包括路径错误、用户无权限、端口占用和环境文件错误。快速重启循环会掩盖根因。
更新与回退
- 准备可回退的新版本。
- 验证依赖、权限和数据库变更。
- 重启或执行应用支持的平滑重载。
- 检查状态、端口、健康接口和日志。
- 失败时恢复旧版本并再次验证。
服务安全边界
尽量使用无登录权限的专用用户,不要默认以 root 运行。强化参数应逐项增加并验证所需路径和能力。
状态对照
| 状态 | 重点检查 |
|---|---|
| 203/EXEC | ExecStart 路径与执行权限 |
| 217/USER | User/Group 是否存在 |
| 立即退出 | 前台模式、环境和应用日志 |
| 重启未启动 | enable 状态与依赖 |
最小单元必须明确
填写 User、WorkingDirectory、完整的 ExecStart 和合理重启策略。秘密不要直接写在公开单元文件;环境文件应限制权限。应用前台运行,让 systemd 跟踪主进程,不用 nohup 或再次后台化。
启动失败只读检查
systemctl status 应用看退出码和最近日志。journalctl -u 应用 -b找第一条错误。- 以同一用户执行启动命令,检查路径、权限和依赖。
- 用
ss核对端口占用,查看是否达到启动限制。
验收与回退
执行 daemon-reload、启动和 enable 后,检查 active、端口、健康页和日志,再重启服务器验证自启。更新前备份单元文件;失败就 stop 新服务、恢复旧文件、daemon-reload 并用旧命令启动。不要通过无限增大重启次数掩盖应用错误。
Linux 怎么用 systemd 管理应用现场验收单
- 入口或命令:SSH 终端创建 /etc/systemd/system/应用.service,执行 daemon-reload/start/enable
- 提交前风险:systemd 不单独收费;错误服务会中断应用或反复重启,不会自动删数据
- 不能继续时:工作目录/环境变量错、用户无权限、端口占用、启动太快退出、Restart 循环、依赖未就绪
- 完成证据:systemctl active/enabled,日志无循环,端口与健康检查通过,重启后自启
- 退出办法:保留旧单元和手工启动命令;失败 stop 新服务、恢复旧文件并 daemon-reload

