很多刚接触 VPS(虚拟专用服务器)的朋友,在辛辛苦苦写完一个 Python 爬虫,或者跑起一个 Node.js 的后端项目时,都会面临一个终极问题:
我把 SSH 终端窗口一关,程序怎么就跟着死了?
于是,大家开始满世界找偏方:
- 第一天,你学会了在命令后面加个神奇的
&符号,比如node app.js &。但这不仅会把满屏的日志拉屎一样倒在终端里,而且一旦程序出错崩溃了,它就彻底消失了。 - 第二天,你学会了
nohup:nohup python3 script.py &。世界终于安静了,日志被塞进了nohup.out。但这玩意不仅难管理(想关掉得用ps查进程号然后kill -9强杀),而且机器重启了你得手动再去敲一遍。 - 第三天,你学会了著名的
screen或tmux(虚拟终端会话)。你把程序放在一个永远不关心的后台黑盒里跑。这在临时调试时很爽,但在生产环境中这简直是一场“野生管理”的灾难。
在 2024 年,如果你想让你亲手写的程序,享受和 Nginx、MySQL 一样“皇帝般”的开机启动、优雅重启、进程守护待遇,你必须学会现代 Linux 系统的终四大管家 —— systemd。
Systemd 的威力:一切皆服务 (Service)
Systemd 从 CentOS 7 和 Ubuntu 16.04 开始,已经彻底接管了 Linux 所有的守护进程(Daemon)。 不管你用的是哪种编程语言,你需要做的只是给这位大管家写一封包含三条核心指令的“委托信”。
这封委托信放在 /etc/systemd/system/ 目录下,通常以 .service 结尾。
3 分钟写出一个完美的 Service 文件
假设你写了一个叫做 mybot.py 的电报机器人脚本(位于 /opt/mybot/ 目录),现在让我们为它写一份完美的 systemd 配置(比如命名为 mybot.service):
[Unit]
Description=My Awesome Telegram Bot
After=network.target
[Service]
Type=simple
User=root
# 你的程序放在哪
WorkingDirectory=/opt/mybot
# 怎么启动这玩意
ExecStart=/usr/bin/python3 /opt/mybot/mybot.py
# 崩溃了怎么办?让它满血复活!
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
这就完事了!就是这么简单且优雅。
拆解神器的魔法:
[Unit]区块:这是这你向管家介绍自己是谁,并且告诉它“请务必在插好网线(网络就绪)之后,再叫我起床(After=network.target)”,不然机器人连不上 Telegram 会报错。[Service]区块:你是谁(什么用户跑它)、你要干什么(具体在哪个目录敲什么命令)、如果干砸了怎么办(Restart=on-failure:如果是意外死亡,请过 5 秒后帮我把它重新拉起来)。[Install]区块:把它注册进入系统的开机流程中。
驾驭大管家:systemctl 的常用魔法阵
写完配置文件,跑一跑下面的命令行,体会一下什么是真正的运维快感(请用 root 权限执行):
- 让管家重新阅读信件(每次改了配置都得敲):
systemctl daemon-reload - 启动它!:
systemctl start mybot - 设为开机自启(永动机模式):
systemctl enable mybot - 看看它现在究竟是活着还是死了(极其详细的彩色状态):
systemctl status mybot - 看看它都在终端里吐出了什么日志(自带滚动追踪):
journalctl -u mybot -f
放弃 screen 和 nohup 吧。在这个一切都在向着容器化和规范化狂奔的年代,Systemd 那几十行简洁的配置,将会极大减少你深夜被报警吵醒的次数。