UPS 断电后,怎么把自动关机脚本写得稳一点

upsc ups@localhost 能读到电池状态,不代表断电时这套链路一定能把机器安全关掉。

UPS 装好只是开始。真正容易出问题的是断电后的几分钟:主机何时关机、Docker 和虚拟机谁先停、来电后是否会留下未清理状态。

这篇只讨论一件事:怎么把“断电后自动关机”写得更稳。

先想清楚:关机不是一个命令

UPS 不是“电没了就执行 shutdown”。它更像一个缓冲区,给系统争取几分钟完成收尾。

常见流程通常是:

  1. 市电断开,UPS 切到电池供电
  2. 监控程序收到事件
  3. 等待一个短暂观察期,避免瞬时掉电误判
  4. 进入关机流程:先停服务,再停宿主机
  5. 电量低到阈值时,执行最终关机

“观察期”很重要。电压抖动、插排误碰,都可能触发一次切电。如果每次都立刻关机,可用性会很差。

一个够用的判断条件

普通场景先抓两个信号就够了:

  • 是否在电池供电:说明市电已经断了
  • 剩余电量或剩余时间:说明还能撑多久

如果监控工具能提供这两个值,脚本就能写得比较实用:

  • 前者决定“要不要准备关机”
  • 后者决定“现在是不是必须关”

一个保守做法是:

  • 断电后先等 60 到 180 秒
  • 如果这段时间市电恢复,退出
  • 如果仍在电池模式,再开始停服务
  • 只在电量低于阈值时执行系统关机

目的不是优雅,而是减少误关机。

脚本最容易忽略的是幂等

UPS 事件可能重复上报,脚本也可能被再次触发,所以幂等很关键。

可以简单理解成:同一个动作重复执行,结果不应该越来越糟。

这些操作最好都按“可重复执行”来写:

  • 已停止的容器,再停一次也不报致命错误
  • 已卸载的网络共享,再执行一次直接跳过
  • 已创建的锁文件,要能判断是不是旧任务残留
  • 已发出的关机命令,不要再触发第二轮清理

一个实用做法是在脚本开头加锁,比如用锁文件或 flock,保证同一时间只有一个实例在跑。否则 UPS 连续上报几次事件,脚本可能并发执行,顺序会乱。

顺序比花哨更重要

如果 Homelab 里既有容器也有虚拟机,先列依赖,再写停机顺序。

比较常见的顺序是:

  1. 先停下载、转码、备份这类高 I/O 服务
  2. 再停数据库、面板、反向代理
  3. 然后停虚拟机或容器运行时
  4. 最后让宿主机关机

原因很直接:

  • 高 I/O 服务最容易在断电时留下损坏
  • 数据库通常需要更完整的退出过程
  • 宿主机必须放最后

如果有 NAS 或远程挂载,也要先梳理依赖关系。不要先把存储断掉,再让还在写数据的服务继续跑。

日志要留,但别写成控制台表演

断电时最怕“看起来执行了,其实没做完”。所以脚本至少要记录三类信息:

  • 什么时候检测到断电
  • 什么时候开始停服务
  • 最后有没有真正执行关机

日志不用复杂,能落到本地文件就够。重点不是格式,而是下次排查时能知道卡在哪一步。

如果条件允许,可以加失败通知,比如发到局域网通知服务、邮件或消息网关。但这不是必须,因为断网或路由器掉电时,外发通知本身就可能不可靠。

一个更稳的最小实现思路

下面这种流程,比单条 shutdown -h now 更接近可用状态。

1. 收到 UPS 事件后先判断

  • 是否确实在电池供电
  • 是否已经有脚本实例在运行

2. 进入短暂等待

  • 睡眠 120 秒
  • 再检查一次电源状态

3. 开始清理

  • 按顺序停止容器、虚拟机、挂载、服务
  • 每一步都允许重复执行
  • 每一步都写日志

4. 最终关机

  • 满足低电量阈值,或等待超时后仍未恢复市电
  • 执行系统关机

这里有个取舍:是“尽快保护数据”,还是“尽量撑到来电”。没有统一答案,要结合电池容量和服务重要性来定。电池小,就早点关;电池足,就多等一会儿。

不要跳过演练

UPS 脚本平时很少有存在感,真停电时才会暴露问题。

演练也别直接拔总闸。更稳妥的做法是:

  • 先确认监控程序能正确读到 UPS 状态
  • 再用测试事件或短时断开市电做验证
  • 观察日志里是否按预期进入等待、清理、关机流程

重点不是“测试一次成功”,而是确认重复触发时也不会乱。尤其是锁、重试、重复停止这几块,建议单独检查。

别把自动关机写成自动事故

UPS 场景里,脚本不需要过度聪明。

比如根据十几个指标动态计算关机时机,理论上很强,实际维护成本也更高;一旦某项数据缺失,行为可能更不稳定。对多数场景来说,清晰的阈值、固定的顺序、可重复执行的步骤,通常已经够用。

如果还要继续完善,优先考虑来电后的恢复策略:哪些服务自动启动,哪些保留人工确认。


UPS 断电后,怎么把自动关机脚本写得稳一点
https://ghost.kasumi.live/2026/04/13/UPS 断电后,怎么把自动关机脚本写得稳一点/
作者
Amadeus
发布于
2026年4月13日
许可协议