systemd 让 Go 后端开机自启、崩溃自动重启:点餐服务的一次实战
systemd 让 Go 后端开机自启、崩溃自动重启:点餐服务的一次实战
先说结论
Go 后端编译出来是一个二进制,跑起来很简单,但“跑起来”和“一直跑着”是两回事:服务器重启后服务不会自己起来,进程崩了也不会自己恢复。用 systemd 接管它,只需要写一个十几行的 unit 文件,就能同时解决开机自启、崩溃自动重启、日志集中管理这三个问题。对只有一台 2 核 2G 云服务器的个人项目来说,这是性价比最高的守护方式。
第一步:写一个最小的 unit 文件
假设后端二进制在 /opt/order/server,监听 8080 端口,配置文件在 /opt/order/config.yaml:
[Unit]
Description=Order Backend Service
After=network.target
[Service]
Type=simple
User=order
WorkingDirectory=/opt/order
ExecStart=/opt/order/server -config /opt/order/config.yaml
Restart=always
RestartSec=5
Environment=GIN_MODE=release
[Install]
WantedBy=multi-user.target
保存为 /etc/systemd/system/order.service,然后执行 systemctl daemon-reload、systemctl enable order、systemctl start order。enable 管开机自启,start 管现在就跑起来,两件事别混在一起:只 start 不 enable,下次重启服务就没了。
第二步:理解 Restart 到底在管什么
Restart=always 的意思是:进程不管因为什么原因退出,systemd 都会把它拉起来。配合 RestartSec=5,每次重启前等 5 秒,避免刚崩就立刻重启、日志被刷爆。但要注意两个边界。第一,如果程序本身一启动就报错退出(比如配置文件路径写错、端口被占用),systemd 会一直重复拉起,systemctl status order 里能看到一连串失败记录,这时候先修配置,别怪 systemd。第二,always 也会在你主动 systemctl stop order 之后不再拉起——手动停就是手动停,systemd 分得清。
User=order 也值得单独说一句:别用 root 跑业务服务。单独建一个无登录权限的系统用户,只给它读写自己数据目录的权限,万一服务有漏洞,攻击者拿到的也只是一个受限用户。建用户只要一条命令:useradd -r -s /usr/sbin/nologin order,然后把 /opt/order 的属主改给它。
第三步:日志不用自己写文件了
Go 程序往标准输出打的日志,systemd 会自动收进 journal,不用再自己维护日志文件。查日志用 journalctl -u order -f 实时看,journalctl -u order --since "1 hour ago" 看最近一小时。日志默认存在 /var/log/journal,磁盘有限的小服务器要记得限制大小,在 /etc/systemd/journald.conf 里加一行 SystemMaxUse=200M,再 systemctl restart systemd-journald,防止日志把 40G 磁盘吃满。
检查清单
systemctl is-enabled order返回 enabled,开机自启才算真正配好。kill掉一次进程,看它是不是在 5 秒后自己回来了。systemctl status order里没有反复重启的失败记录。- 服务以非 root 用户运行,数据目录权限只给该用户。
- journal 磁盘上限设好了,
journalctl --disk-usage看一眼实际占用。
systemd 是 Linux 服务器自带的进程管家,不用再装 supervisor 之类的额外工具。对个人项目来说,先把这一个 unit 文件写对,后面再上 Docker、再做多副本,都是在这个基础上的加法。
- 点赞
- 收藏
- 关注作者
评论(0)