一個機器人在伺服器上「不工作」有兩種方式。明顯的那種:您一關 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。
評論
目前還沒有評論。歡迎成為第一位。