用 systemd 管理长期运行脚本的几个实用技巧
【摘要】 Restart 策略、启动依赖、日志轮转、环境变量隔离与优雅停止,把脚本变成可靠服务的六件事,附一份可直接套用的 unit 模板。
把脚本扔进 nohup 是能跑,但机器重启就没了、崩了也不会自愈、日志越滚越大。用 systemd 托管成本很低,这篇列几个真正有用的点。
一、最小可用模板
[Unit]
Description=My Long Running Job
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
Environment="TZ=Asia/Shanghai"
EnvironmentFile=-/etc/myapp/env
ExecStart=/usr/bin/node /opt/myapp/main.js
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
几个容易漏的:After=network-online.target 保证网络就绪(network.target 不够),EnvironmentFile 前面的 - 表示文件不存在也不报错。
二、Restart 策略要选对
always:退出就重启,适合常驻服务on-failure:只有非 0 退出才重启,适合定时任务RestartSec别设太小,否则崩溃循环会把日志刷爆、把 CPU 打满
还可以加 StartLimitBurst=5 和 StartLimitIntervalSec=60,60 秒内崩 5 次就放弃,避免无限重启。
三、优雅停止
默认 systemd 发 SIGTERM,等 90 秒后才 SIGKILL。如果脚本需要收尾(关数据库连接、写完缓冲区),必须自己监听 SIGTERM:
process.on('SIGTERM', async () => {
await cleanup();
process.exit(0);
});
收尾时间超过默认值的,把 TimeoutStopSec=30 调合适,否则会被硬杀。
四、日志不要自己写文件
让 systemd 收走(StandardOutput=journal),然后设 SystemMaxUse=500M 限制 journal 总量。比自己在脚本里做轮转省事得多。
五、用户级服务 vs 系统级
不需要 root 的脚本用 systemctl --user 更安全,但要 loginctl enable-linger <user>,否则用户登出后服务会被停掉——这个坑几乎每个人都会踩一次。
六、改动后必须 daemon-reload
改完 unit 文件不 systemctl daemon-reload,restart 用的还是旧配置,容易以为是代码没生效。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)