用 systemd 管理后台服务:开机自启和日志不用再手写脚本
在云服务器上跑一个长期服务时,很多人习惯用 nohup 或 screen 挂着进程。机器一重启,服务就没了;崩溃了也不知道,只能靠人工巡检。Linux 发行版自带的 systemd 可以优雅地解决这些问题:统一启动、失败自动重启、日志集中查看。本文用一个简单的 Python HTTP 服务说明怎么写 unit 文件。
一、什么是 unit 文件
systemd 用「单元」(unit)描述要管理的对象。服务对应的是 .service 文件,常见位置是 /etc/systemd/system/。写好后执行 sudo systemctl daemon-reload 让 systemd 重新扫描,再用 start / enable 控制运行和开机自启。
二、最小可用的 service 示例
假设项目在 /opt/myapp,虚拟环境里的启动命令是 .venv/bin/python app.py,可以这样写:
[Unit]
Description=MyApp HTTP service
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/.venv/bin/python app.py
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
Type=simple 表示 ExecStart 启动的进程就是主进程。Restart=on-failure 让异常退出后自动拉起;正常 stop 不会重启。User 建议用非 root 账号,降低被入侵后的影响面。
三、常用操作命令
启用并立即启动:sudo systemctl enable --now myapp。查看状态:systemctl status myapp。看最近日志:journalctl -u myapp -n 100 --no-pager,加 -f 可以实时跟踪。改完代码后一般 sudo systemctl restart myapp 即可。禁用开机自启用 disable,不影响当前是否在跑。
四、环境变量与密钥
不要把密钥硬编码进 unit 文件再提交到 Git。可以用 Environment=KEY=value 写非敏感配置,敏感项放到单独的 EnvironmentFile=/etc/myapp.env,并把该文件权限设为 600、属主为 root。应用里用 os.environ 读取即可。换环境部署时只改 env 文件,不必改 service 定义。
五、常见坑
第一,改完 .service 忘记 daemon-reload,systemctl 仍用旧定义。第二,WorkingDirectory 或 ExecStart 路径写错,status 里会看到 exit code,用 journalctl 看具体报错。第三,用了相对路径依赖当前目录,在 systemd 下可能找不到文件,尽量写绝对路径。第四,Type 选错:若进程会自己 fork 成守护进程,应改用 Type=forking,并指定 PIDFile。
小结
把长期运行的服务交给 systemd,比手写启停脚本更稳:开机自启、失败重启、日志可查。先写一个最小的 .service 跑通,再按需要加环境变量、资源限制和依赖顺序。云主机重启之后,服务还能自动回来,运维压力会小很多。
- 点赞
- 收藏
- 关注作者
评论(0)