维护站点一段时间后,我发现自己每周都在重复同样的动作:构建、上传、刷新缓存、检查证书、确认备份、跑一遍链接检查。单次都不长,但加起来每周要花一两个小时,而且很容易漏。
漏掉的后果不一定立刻出现:证书忘了续,某天突然打不开;备份失败了没发现,真正需要时没有可用副本。这些事不适合靠记性。
先列出重复动作
我没有一上来就写脚本,而是先记录了两周。最后列出来的清单大概是:
| 动作 | 频率 | 耗时 | 出错后果 |
|---|---|---|---|
| 构建并发布 | 每周 1—2 次 | 15 分钟 | 页面不更新 |
| 刷新 CDN | 每次发布 | 5 分钟 | 读者看到旧内容 |
| 证书检查 | 每周 | 5 分钟 | 证书过期 |
| 备份检查 | 每周 | 5 分钟 | 数据丢失 |
| 链接检查 | 每月 | 20 分钟 | 死链 |
| 图片压缩 | 每次加图 | 10 分钟 | 页面变慢 |
这张表让我看清一件事:真正耗时的不是单个动作,而是“切换上下文”——每次都要登录、找命令、回忆步骤。自动化的价值,很大一部分是把这个切换成本消掉。
分层:哪些放本地,哪些放服务器
我把自动化分成两层。
构建与发布放在 CI。 提交代码后自动构建,构建成功后同步到服务器。这样本地不需要装构建环境,发布也不依赖我的电脑是否开机。
服务器上的定时任务用 systemd timer。 证书检查、备份、日志清理这类事和代码发布无关,放在服务器上更合适。相比 crontab,systemd timer 的好处是能查状态、能看日志、能设置依赖。
一个最小的 timer 大概是这样:
1 | # /etc/systemd/system/axis-backup.timer |
Persistent=true 很重要:机器在 03:30 关机时,下次启动会补跑一次,而不是直接跳过。
脚本要能安全失败
自动化最危险的不是“没跑”,而是“跑了一半”。我给自己定了几个规则:
- 幂等:同一脚本重复执行,结果一致;
- 先 dry-run:涉及删除、覆盖的脚本先打印将要做什么,确认后再执行;
- 失败即停:任何一步失败就退出,不继续往下走;
- 有超时:网络操作设置超时,避免挂住;
- 有锁:防止上一次没跑完,下一次又启动。
一个简化过的备份脚本骨架:
1 |
|
set -euo pipefail 让脚本在错误时立刻退出,flock 防止并发,restic check 做一次抽样校验。这些都不复杂,但能避免很多“以为成功了”的情况。
失败必须被看见
自动化之后,我最担心的不是它出错,而是它出错了没人知道。所以每个任务都接入了同一条通知通道:失败发消息,连续失败再发一次。
通知里包含三样东西:哪个任务、哪一步失败、日志在哪。没有这三样,通知只会让人焦虑,不能帮助处理。
我没有自动化的事
有几件事我刻意保留人工:
- DNS 切换:影响面大,宁可手动确认;
- 删除数据:再小心也不为过,必须人工二次确认;
- 大版本升级:可能改变行为,需要先看变更说明;
- 发布前的最终检查:自动构建通过不代表内容没问题。
自动化的边界不是“能不能做”,而是“出错后我能不能承受”。不可逆的操作,宁可慢一点。
时间账
现在每周花在重复工作上的时间,从一两个小时降到十几分钟,主要是看一眼通知和偶尔处理失败。
但比时间更重要的是心态变化:以前我总有一根弦绷着,怕忘了续证书、忘了备份;现在这些事有固定的执行者和失败通知,我可以把注意力放在写作和真正的优化上。
工具是梁,不是目的。好的自动化应该让人感觉不到它的存在,只在出问题时提醒你:这里需要看一眼。