写了个Python脚本、部署了个Bot或Web应用,怎么让它开机自动启动、崩溃了自动拉起、还能方便地管理和看日志?答案不是nohup也不是screen,而是systemd服务。这是Linux下托管长期运行程序的标准做法。本文教你写出规范的systemd服务。
一、为什么用systemd,而不是nohup/screen?
nohup和screen能让程序在后台跑,但有硬伤:服务器重启后不会自动恢复、程序崩溃了不会自动重启、日志管理混乱。systemd解决了这一切:
- 开机自启:服务器重启,你的程序自动回来;
- 崩溃自愈:程序挂了自动重启,大幅提升可用性;
- 统一管理:start/stop/restart/status一套命令;
- 日志集成:journalctl统一查看日志。
二、写一个systemd服务文件
在 /etc/systemd/system/ 下创建服务文件,比如 mybot.service:
[Unit]
Description=My Python Bot
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/mybot
ExecStart=/opt/mybot/venv/bin/python /opt/mybot/bot.py
Restart=always
RestartSec=5
User=www-data
[Install]
WantedBy=multi-user.target
关键字段解释:
- After=network.target:等网络就绪再启动(联网程序必加);
- WorkingDirectory:程序工作目录;
- ExecStart:启动命令,必须用绝对路径(常见坑);
- Restart=always:崩溃后总是重启(核心的自愈能力);
- RestartSec=5:重启前等5秒,避免疯狂重启;
- User:用哪个用户运行(安全起见别用root跑业务)。
三、启用和管理服务
systemctl daemon-reload # 改动服务文件后必须reload
systemctl enable mybot # 设置开机自启
systemctl start mybot # 启动
systemctl status mybot # 查看状态(排错第一步)
systemctl restart mybot # 重启
systemctl stop mybot # 停止
enable --now 可以一步完成”设为自启+立即启动”。
四、查看日志
journalctl -u mybot # 查看该服务所有日志
journalctl -u mybot -f # 实时滚动(排故障用)
journalctl -u mybot --since "1 hour ago" # 看最近1小时
journalctl -u mybot -n 100 # 看最后100行
程序的print输出、错误信息都会被systemd收集,journalctl统一查看,比自己管理日志文件方便得多。
五、进阶配置
- 环境变量:用
Environment="KEY=value"或EnvironmentFile=加载环境变量(敏感信息如Token放这里,别硬编码); - 资源限制:
MemoryLimit=、CPUQuota=限制服务的资源占用,防止单个服务吃垮机器; - 依赖关系:用
Requires=、After=声明服务启动顺序(如应用依赖数据库先启动)。
六、常见排错
- 服务启动失败:先看
systemctl status和journalctl -u,错误几乎都写在里面; - ExecStart路径错:用绝对路径,虚拟环境要指向venv里的解释器;
- 权限问题:User指定的用户对WorkingDirectory要有权限;
- 改了不生效:忘了
daemon-reload。
结论
systemd是让程序”专业地跑起来”的标准方式:开机自启、崩溃自愈、统一管理、日志集成。无论是TG Bot、Web应用、还是自定义脚本,都值得花五分钟写个service文件托管起来。在你的香港VPS上把你的第一个程序做成systemd服务,从此不再担心它半夜悄悄挂掉没人管。