用 systemd 管理 python 进程比 nohup 可靠得多,因其支持自动重启、资源限制、日志集成与系统生命周期对齐;需配置绝对路径、正确 type、user、显式 venv、-u 参数、sigterm 处理及 workingdirectory 等关键项。

用 systemd 管理 Python 进程比 nohup 可靠得多
脚本扔后台跑着跑着就没了,八成是没用 systemd。它能自动拉起崩溃进程、限制内存、记录日志,还和系统启动/关机流程对齐。nohup 和 & 本质只是绕过终端挂起信号,不解决进程生命周期管理问题。
常见错误现象:ps aux | grep myscript 找不到进程,但脚本明明“在跑”;或者重启服务器后服务没起来。
- 写一个
/etc/systemd/system/myservice.service文件,核心字段必须有:ExecStart=/usr/bin/python3 /opt/myapp/main.py(路径务必写绝对路径) -
Type=simple最常用;如果脚本启动后会 fork 出子进程再退出(比如某些 flask 启动方式),改用Type=forking并配好PIDFile= - 加
Restart=always和RestartSec=5,否则进程一崩就真没了 - 别漏掉
User=字段——默认以root运行很危险,指定普通用户更安全
venv 必须在 service 文件里显式激活
systemd 不读 shell 的 .bashrc 或 .profile,所以直接写 python3 main.py 很可能用的是系统 Python,而不是你装了 requests、sqlalchemy 的那个环境。
使用场景:依赖包多、需要隔离版本、或用了 poetry/pipenv 管理的项目。
立即学习“Python免费学习笔记(深入)”;
- 不要用
source venv/bin/activate && python main.py——systemd不支持 shell 内建命令链式调用 - 正确做法:用
ExecStart=/opt/myapp/venv/bin/python /opt/myapp/main.py - 如果依赖 C 扩展(如
psycopg2),确保编译环境一致:在目标机器上用相同 Python 版本重建venv,别直接复制 - 想省事?把
venv放进项目目录,用相对路径容易出错,一律用绝对路径
日志不能只靠 print(),得对接 systemd-journald
脚本里狂打 print("got request"),结果 journalctl -u myservice 什么都看不到——大概率是 Python 缓冲了 stdout/stderr。
性能影响:不处理缓冲,日志延迟高,崩溃时最后几条输出直接丢失。
- 启动命令末尾加
-u参数:ExecStart=/opt/myapp/venv/bin/python -u /opt/myapp/main.py - 代码里也建议显式刷新:
print("starting...", flush=True) - 避免自己写文件日志:和
journalctl冲突,权限难管,轮转逻辑还得自己写 -
journalctl -u myservice -f实时看日志,比翻/var/log/下一堆文件快得多
信号处理不当会让 systemd stop 变成 kill -9
systemd stop myservice 执行完,进程还在,接着 systemd 就发 SIGKILL 强杀——说明你的 Python 没响应 SIGTERM。
为什么重要:强杀可能丢数据(比如正在写数据库事务、缓存未刷盘)、无法执行清理逻辑(关闭连接、释放锁)。
- 必须注册
signal.signal(signal.SIGTERM, cleanup_handler),不能只靠try/except KeyboardInterrupt -
cleanup_handler里做关键收尾:关闭数据库连接池、取消 pending task、写 shutdown marker 到 redis - 别在 handler 里做耗时操作(比如等 http 请求返回),
systemd默认只给 90 秒,超时就强杀 - 测试方法:
sudo systemctl stop myservice && journalctl -u myservice | tail -10,确认看到 “shutting down…” 类日志
最难搞的其实是环境变量和工作目录——systemd 默认清空大部分变量,CWD 是 /。哪怕只差一个 WorkingDirectory=/opt/myapp 或漏写 Environment=PYTHONPATH=/opt/myapp/lib,服务就静默失败。这些细节不报错,只让你反复怀疑人生。