一、为什么要服务化
一个程序能在终端运行,不代表适合部署。真正部署到 Linux 设备或服务器时,需要解决:
- 开机自动启动。
- 异常退出自动重启。
- 统一查看日志。
- 使用非 root 用户运行。
- 控制启动顺序。
- 优雅停止。
Linux 现代发行版通常使用 systemd 管理服务。
二、最小 service 文件
创建:
1 | /etc/systemd/system/my_app.service |
内容:
1 | [Unit] |
加载:
1 | sudo systemctl daemon-reload |
启动:
1 | sudo systemctl start my_app |
查看状态:
1 | systemctl status my_app |
开机启动:
1 | sudo systemctl enable my_app |
三、查看日志
查看最近日志:
1 | journalctl -u my_app -n 100 |
实时日志:
1 | journalctl -u my_app -f |
按时间过滤:
1 | journalctl -u my_app --since "2026-06-21 10:00:00" |
如果程序把日志输出到 stdout/stderr,systemd 会自动收集到 journal。
四、优雅停止
停止服务:
1 | sudo systemctl stop my_app |
systemd 默认会发送 SIGTERM。程序应该捕获 SIGTERM,完成资源清理后退出。
应用中需要处理:
- 停止接收新请求。
- 保存必要状态。
- 关闭文件。
- 关闭 socket。
- 等待工作线程退出。
不要依赖 kill -9,SIGKILL 无法清理资源。
五、使用非 root 用户
创建用户:
1 | sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp |
service:
1 | [Service] |
目录权限:
1 | sudo mkdir -p /var/lib/my_app /var/log/my_app |
服务不应该默认用 root 跑。只有确实需要特权端口、硬件访问或系统配置时,才考虑授权。
六、环境变量
可以在 service 中设置:
1 | [Service] |
也可以使用环境文件:
1 | [Service] |
/etc/my_app/my_app.env:
1 | APP_ENV=prod |
七、重启策略
常见配置:
1 | Restart=on-failure |
含义:
- 失败时重启。
- 3 秒后重启。
- 60 秒内最多尝试 5 次。
这样可以避免程序一直崩溃、systemd 疯狂拉起。
八、常见排错
8.1 service 修改后没生效
执行:
1 | sudo systemctl daemon-reload |
8.2 手动能运行,systemd 不能运行
常见原因:
- 工作目录不同。
- 环境变量不同。
- 权限不同。
- 相对路径失效。
建议在 service 中使用绝对路径:
1 | WorkingDirectory=/opt/my_app |
8.3 日志不足
先看:
1 | journalctl -u my_app -n 200 --no-pager |
程序启动时应该打印配置路径、监听端口、版本号和关键依赖状态。
九、推荐 service 模板
1 | [Unit] |
EnvironmentFile 前面的 - 表示文件不存在也不算失败。
十、总结
服务化不是把程序丢到后台运行。一个合格的 Linux 服务需要可启动、可停止、可重启、可观察、可排错。
systemd 是部署 Linux 应用的基础工具。掌握它以后,应用从“能跑”到“能长期稳定运行”会跨过一大步。
- 本文链接: https://blog.hansong.icu/2026/06/21/Linux_Dev_Systemd_Service/
- 版权声明: 本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。