1.4 镜像、快照与弹性伸缩:半夜宕机后的补救方案
写这一节的时候,窗外刚下完雨。上个月某个凌晨两点,我的社区服务器毫无征兆地挂了——监控告警狂响,SSH 连不上,页面 502。那一晚之后,我把快照、镜像和弹性伸缩这几件事从知道变成了做到。这一节就是那次事故的完整复盘,以及之后定下的备份规矩。
一、事故:凌晨两点的一声告警
先说结论式的经验:宕机不可怕,可怕的是你没有快速恢复的手段。
那天两点出头,云监控的离线告警把我吵醒。我爬起来试 SSH,连接超时;控制台看实例状态是运行中,但 CPU 监控曲线在一点五十左右突然拉到 100% 然后变成一条直线——服务器卡死了,不是进程崩了,是整个系统都不响应了。
我在控制台点了重启,等了五分钟,服务回来。日志里没留下有效线索,大概是某个突发流量把内存和 IO 都压垮了。机器活着,但故障时间已经过去四十分钟——对一个刚起步的社区来说,凌晨挂四十分钟影响不大,但如果是白天搞的活动高峰呢?我不敢想。
事后我把这次故障的处理过程也复盘了一遍:
| 阶段 | 耗时 | 本可以缩短的办法 |
|---|---|---|
| 发现故障 | 约 10 分钟 | 告警唤醒,无法更快 |
| 确认原因 | 约 15 分钟 | 监控曲线只看到 CPU 飙升,缺少内存明细 |
| 重启恢复 | 约 15 分钟 | 有快照可回滚就不靠重启赌运气 |
| 验证服务 | 约 5 分钟 | 加健康检查接口,自动化验证 |
真正让我难受的是中间那十五分钟:明知道机器卡死,却不知道是哪个进程的问题。从那天起我给监控加了内存、磁盘 IO 两类指标,又在应用里埋了健康检查接口。告警和监控的完整配置在第五篇,这里只说一句:出事时看得见现场,比事后猜原因重要一百倍。
二、快照:云硬盘时间点的副本
事后我做的第一件事是给系统盘和数据盘都拍快照。快照就是云硬盘在某个时间点的数据副本,详细的概念说明可以参考云服务器概述里的存储相关章节。它的价值在于:
- 回滚:系统搞坏了、数据误删了,一键回滚到快照时刻。
- 重建:用快照做镜像,新机器开出来环境一模一样。
- 零中断:拍快照不用停机。
我给自己定的快照策略:
| 项目 | 系统盘 | 数据盘 |
|---|---|---|
| 快照频率 | 每周一次(改动少) | 每天一次(数据多) |
| 保留数量 | 最近 4 份 | 最近 7 份 |
| 触发方式 | 定时快照策略 | 定时快照策略 |
| 回滚前注意 | 先确认问题已定位 | 回滚会覆盖现有数据 |
提醒一点:快照回滚是覆盖操作,当前数据会没掉。不确定的时候,先手动拍一份当前状态的快照再回滚旧的。
还有两件小事值得知道:快照是按容量收费的,我两块盘加起来 150G,每月快照费用就几块钱,性价比很高;另外快照只覆盖云硬盘上的数据,内存里的数据是保不住的——所以应用层面自己该做的持久化(缓冲数据落地、定时保存)一件都不能少,快照不是应用层持久化的替代品。
定了策略不代表能用,我后来每个月会做一次故障演练:挑凌晨没什么用户的时候,关掉一台机器,逼自己用快照和镜像在十五分钟内把服务恢复到另一台机器上。前两次演练手忙脚乱,第三次就熟练了。真出事的时候能不能稳住,全靠平时练过。
三、自定义镜像:十分钟重建一套环境
快照救的是数据,自定义镜像救的是时间。
我第一次迁移服务器时,新机器开出来,环境重装一遍:Nginx、Python、1Panel、各种配置文件、系统调优参数,前前后后搞了两小时。第二个月我就学乖了:把调好的系统做成自定义镜像,以后开新实例直接用镜像启动,开机就是一套配好的环境,十分钟就能拉起一台新机器。
| 恢复手段 | 耗时 | 效果 |
|---|---|---|
| 手动重装环境 | 1~2 小时 | 容易漏配 |
| 自定义镜像开机 | 约 10 分钟 | 环境与原机一致 |
| 快照回滚 | 约 10 分钟 | 数据回到快照时刻 |
我的做法是每季度更新一次自定义镜像:系统大更新之后、装了新组件之后,都重新做一份。镜像做多了也占空间,保留最近两三份够用。
另外还有个小技巧:重要节点前手动拍一份快照。我每次升级大版本、改数据库结构之前,都先拍快照再动手。成本几乎为零,但把不可逆操作变成了可逆的——这套习惯在家里自建服务器时也适用,自建环境怎么做备份可以参考NAS 与家庭服务器实战。
顺带一提,服务器上的应用环境如果用面板管理,备份和迁移会简单不少。我用的是 1Panel,它有自动备份和快速迁移功能,面板相关的玩法见1Panel 运维面板实战,遇到迁移后服务起不来的问题,排查思路可以翻1Panel 常见问题。
四、弹性伸缩:让流量高峰自己过去
那次宕机的根源是突发流量。云服务器有个功能叫弹性伸缩,能根据负载自动加减实例:CPU 超过设定阈值就自动扩容,降下去再自动缩回来,配合负载均衡把流量分发到多台机器。
这个方案我最终没一上来就用,原因是:我的应用当时是有状态的(会话存在本地),多台实例之间没做好共享,贸然扩容会有登录态丢失的问题。正确的姿势是先把会话挪到外层(比如数据库或缓存),再开伸缩组。我的打算是等下一波活动流量来了再上,先把单机的容灾做好。
伸缩策略的参考配置:
| 指标 | 扩容阈值 | 缩容阈值 | 说明 |
|---|---|---|---|
| CPU 利用率 | > 70% 持续 5 分钟 | < 30% 持续 10 分钟 | 最常用的指标 |
| 外网带宽 | > 80% 持续 5 分钟 | < 20% 持续 10 分钟 | 流量型场景 |
| 最小实例数 | 1 | — | 保证任何时候有机器兜底 |
几个配置上的提醒:冷却时间别忘了设,不然机器刚扩容指标还没稳定,系统反复增增减减;最大实例数要结合预算封顶,不然一次异常流量可能把你账单拉爆;缩容阈值要比扩容阈值低足够多,避免在临界点附近震荡。弹性伸缩救的是预期内的流量波动,如果是被恶意流量打了,伸缩只会帮攻击者占用更多资源,那种情况得靠防护策略,是另一个话题。
五、做一次故障演练
方案写在文档里和真的会做,是两回事。我第二个月搞了一次演练:挑一个周日凌晨,故意在控制台把实例关机,然后计时,看自己多久能把服务恢复。
结果很受刺激:第一次演练我花了五十分钟,中间因为没记住 1Panel 的后台端口又去翻文档。但收获很大——我发现恢复流程里真正卡时间的是那些平时不在意的细节:域名的 DNS 缓存、Nginx 的证书路径、数据库里 remembered 的连接串。后来我把恢复手册细化成了三页纸:第一页是联系人和服务清单,第二页是每个服务的恢复命令,第三页是验证步骤。真出事的时候按页翻,不用动脑子——凌晨两点的大脑,是不值得信任的。
| 演练次数 | 恢复耗时 | 卡在哪里 |
|---|---|---|
| 第 1 次 | 50 分钟 | 端口、证书路径都要现翻文档 |
| 第 2 次 | 25 分钟 | 手册不全,少了 DNS 切换步骤 |
| 第 3 次 | 12 分钟 | 只差开机和验证 |
如果没有快照和镜像,演练根本无从谈起——重装环境就不是几十分钟的事了。这也是我把这两件事看得比弹性伸缩还重的原因:伸缩是优化项,恢复能力是保命项。
六、现在的容灾方案
一套组合拳下来,我现在的基础设施长这样:
- 云数据库 MySQL 主从自动切换,数据库层故障不怕(第二篇细讲)。
- 每日快照 + 每季度镜像,系统和数据都能快速恢复。
- 云监控盯着 CPU、内存、带宽,超阈值先告警再升级。
- COS 里存着图片原文件,服务器挂了图片也不丢(第三篇细讲)。
这一套配下来,单点故障的风险降低了很多。半夜再被吵醒的概率小了,醒来了也知道下一步该点什么。云监控和告警会先于用户告诉我哪里不对(第五篇细讲),数据库主从切换替我兜住数据层的故障,快照和镜像兜住机器层面的故障。层层兜底,才是一个小项目能安心跑下去的底气。
上云这件事,最贵的成本不是服务器费用,是出了事没有预案。快照和镜像就是给自己留的后悔药,平时不起眼,出事时能救命——这是我花了一个凌晨两点换来的教训。
延伸阅读
- 云服务器概述:快照、镜像与云硬盘概念
- 1Panel 运维面板实战:面板的自动备份与快速迁移
- NAS 与家庭服务器实战:自建环境下的备份方案对比
