让服务自己活过来:我给云主机做的三层自动恢复实践
过去一个多月,我手里一台开发用的云主机被平台重置了几十次。所谓重置,就是整台机器回到初始状态:系统包没了、自己建的用户没了、正在跑的服务也没了,只剩数据盘上一个目录还在。头几次我都是手动重装、手动改配置、手动拉服务,一次要折腾小半个小时,而且重置专挑半夜来,第二天一早先得花时间“复活”环境,才能开始干正事。
折腾几次之后我换了思路:既然重置防不住,那就让恢复这件事不需要人。最后做成的方案一共三层,跑了一个多月,基本再没手动救过火。
第一层:把“怎么恢复”写成一份幂等脚本
手动恢复最大的问题不是慢,是每次都要回忆“上次我都改了啥”。所以第一步是把所有人工步骤沉淀成一个恢复脚本:装哪些基础包、建哪个用户、授权文件从哪恢复、配置文件长什么样、服务按什么顺序启动,全写死在脚本里。
这份脚本有两个硬要求。一是所有需要长期保存的东西,只放在那个不会被重置的持久化目录里,包括脚本本身、配置备份、密钥备份。二是脚本必须幂等:跑一次和跑十次结果一样,已存在的跳过,缺失的补上。这样无论谁来触发、在什么状态下触发,都不会把环境越修越坏。
第二层:开机钩子加定时巡检,双保险
光有脚本不够,得有人在重置后的第一时间调用它。我用了两个触发点:一个是系统启动阶段的钩子,机器一起来就先跑一遍恢复;另一个是每隔几分钟执行一次的健康巡检,看门狗逻辑很简单:逐项检查关键服务在不在,不在就跑恢复脚本,在就什么都不做,安静退出。
双保险的原因是两个触发点各有盲区:启动钩子偶尔会因为执行顺序问题漏掉个别组件,定时巡检正好补位;而巡检的间隔期内如果只靠它,服务要中断好几分钟,启动钩子又能把这个窗口压到最短。
巡检里我踩过一个很蠢的坑:用进程名查服务在不在时,检查命令自己的命令行里就带着被查的关键词,结果把自己也匹配上了,误报“服务正常”。解决办法是查的时候给关键词加个小技巧让它匹配不到自己的命令行,或者干脆用更精确的进程查询方式。这个坑听起来小,但它让我的巡检“假绿”了好几天——监控说一切正常,实际服务早没了。
第三层:恢复完了要做端到端验证
这是最重要的一层:进程存在,不等于服务可用。我见过进程明明活着,却卡在一次没完成的握手里,既不报错也不干活。所以每次恢复之后,巡检还会多做一步:从外部视角真正连一次目标端口,读到预期的响应才算恢复成功;连不上就继续重试或告警,而不是看进程还在就宣布胜利。
另外一个教训是验证口径要统一。我给恢复状态定了一个唯一的判定命令:它输出成功,才对人说“恢复了”;它没通过,哪怕十个指标里九个都绿,也只说“还在恢复”。避免了那种各说各话、最后谁也不知道到底好没好的情况。
写在最后
这套东西没有用任何高大上的编排工具,就是脚本、定时任务和健康检查的老三样。真正起作用的是三个观念:第一,假设环境随时会没,按“能重建”而不是“不会坏”来设计;第二,恢复动作全部脚本化且幂等,不依赖人的记忆;第三,验证要从使用者的角度做端到端确认,不信进程表。
如果你用的是抢占式实例、临时沙盒或者任何会被回收的环境,这套思路应该都能直接套。毕竟机器可以随便重置,但人的睡眠不该被它重置。
- 点赞
- 收藏
- 关注作者
评论(0)