用 systemd 管理长期运行脚本的几个实用技巧

举报
yd_274788088 发表于 2026/10/27 00:33:15 2026/10/27
【摘要】 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)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。