一个机器人在服务器上“不工作”有两种方式。明显的那种:你一关 SSH 它就停。阴险的那种:它好好跑了两天,凌晨四点在某个未处理的错误上崩了,你几个小时后才在有人问它为什么下线时发现。两种有同一个解法,而且不是“记得重启它”——而是把这活交给 systemd,它替你保活,让你不必操心。
为什么你登出它就死
如果你在 SSH 会话里用 python bot.py 启动了它,那进程是那个会话的子进程。关掉会话,进程跟着一起没。nohup 和 & 糊过了这个,但它们不给你崩溃重启、也不给你开机启动——所以你解决了小问题、留下了大问题。
真正的解法:一个 systemd 服务
这就是全部。创建 /etc/systemd/system/mybot.service:
[Unit]
Description=My bot
After=network-online.target
[Service]
WorkingDirectory=/home/youruser/mybot
ExecStart=/home/youruser/mybot/venv/bin/python bot.py
Restart=always
RestartSec=5
User=youruser
Environment=API_KEY=...
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
两行在挑大梁:
Restart=always—— 机器人崩了,systemd 在 5 秒内把它拉回来。那个凌晨四点的死亡变成一次没人注意的 5 秒闪断。enable—— 它在重启后自己再次启动。不会再有“哦,服务器重启了,我忘了把一切都重新拉起来”。
当它还在闹脾气时——读日志
一个不停崩溃循环的机器人,不是靠更用力地重启修好的;确实有东西出了问题。systemd 收集 stdout/stderr,所以:
systemctl status mybot # 在线还是下线、上次退出码
journalctl -u mybot -n 100 # 最近日志 + 它死在的那个错误
journalctl -u mybot -f # 实时跟随
原因几乎总是就在那儿:一个缺失的环境变量、一个未处理的异常、一次 API 超时、一次 OOM 击杀。修那个——Restart=always 是一张安全网,不是一个真实 bug 的解药。
小贴士:如果日志显示机器人因内存被杀,你已经长到机器装不下了——看配置指南。
什么时候 tmux 或 pm2 反而更合适
systemd 不是唯一答案,只是最好的默认:
- tmux —— 对一次快速测试或盯着一个交互式进程很完美。跑、分离、之后重连。但它不会崩溃重启、也熬不过一次重启,所以不适合生产。
- pm2 —— 如果你本就在 Node 世界、想要它的进程面板也合理。代价是:pm2 本身是一个你现在得保活的进程(通常……靠 systemd)。对一个机器人,那是你不需要的一层。
对单个常开机器人或代理,systemd 是真正管用的最简单的东西——它已经在服务器上、不用额外工具,开箱就做重启、开机启动和日志。
诚实的一句话
正常运行时间不是关于一台更大的服务器或更多的自律——而是关于别把你的进程绑到你的笔记本上。用一个带 Restart=always 和 enable 的 systemd unit 把它包起来,出问题时查 journalctl。做一次,你的机器人无论你盯着还是睡着都保持在线。(新机器?先锁死它——一个 7×24 的机器人也是一个 7×24 的目标。)
需要个地方跑它? 一个 Nano 套餐($3/月) 让机器人 7×24 存活——其余交给 systemd。
评论
暂无评论。来做第一个吧。