大促来了扩容来不及?弹性伸缩与容量预热避坑指南

去年双11,一个电商客户提前做了扩容。凌晨开始流量涨了3倍,他们很从容。结果00:30突然一波脉冲,流量瞬间再翻倍。自动伸缩规则检测到CPU高了才扩容,新实例从启动到接流量花了将近3分钟。这3分钟里,大量用户请求超时,订单流失。
事后复盘,他们发现:规则的检测周期30秒,加上冷却时间120秒,再等实例启动,加起来确实将近3分钟。这是指标触发扩容的死穴:等指标高了再扩,已经晚了。
今天聊聊弹性伸缩与容量预热。不是那种“弹性伸缩很重要”的废话,而是帮你理清楚:指标触发、定时伸缩、预测伸缩怎么选?扩容冷却怎么设?缩容怎么保?大促前怎么预热?
01 三种伸缩策略,不是只有指标触发
很多人一说到弹性伸缩,就想到“CPU高了就加机器”。这只是其中一种,往往最被动。
策略一:指标触发伸缩
根据CPU、内存、QPS、队列长度等实时指标决定扩缩。
优点:自适应,不用提前预测。
缺点:有延迟。从指标采样到实例就绪,往往要几分钟。
适合:日常业务波动,对延迟不敏感。
策略二:定时伸缩
根据历史规律,提前设置好扩缩计划。
优点:准时,不依赖指标。0:00流量起来,23:55实例已经准备好了。
缺点:需要知道规律,突发情况不适用。
适合:大促、秒杀、早晚高峰等可预测的流量。
策略三:预测伸缩
基于历史指标,用机器学习预测未来流量,提前扩容。
优点:比定时更智能,能适应业务增长趋势。
缺点:平台支持有限(如AWS预测伸缩)。
适合:增长趋势明显、周期性强的业务。
那家电商大促用的是指标触发。高峰期脉冲来了才扩,晚了。后来改成定时伸缩,大促前先把实例拉到预期水位,从容很多。
02 扩容冷却:别让系统来回折腾
扩容冷却(cooldown)是指一次扩容后,等待一段时间才允许下一次扩容。
目的:防止频繁扩缩,给新实例稳定时间。
太短:刚扩完又来一波,会连续扩,浪费资源,也容易震荡。
太长:错过后面的扩容需求,流量来了扩不动。
建议:根据实例启动时间设。一般冷却时间=实例预热时间+几分钟余量。那家电商的实例启动要2分钟,冷却设300秒,够用。
缩容也有冷却,建议比扩容冷却更长。流量降了可能还会回来,别急着缩。
03 缩容保护:别把弹药提前撤走
流量降了,系统自动缩容是好事,省钱。但缩太快,流量反弹就崩。
缩容常见坑:
冷却时间太短:流量刚降5分钟就缩,结果半小时后又来一波,实例不够。
阈值太敏感:CPU低于30%就缩,下午自然回落也会触发。
一次缩太多:从10台缩到2台,再来流量就崩。
保护策略:
缩容冷却时间比扩容更长。如扩容冷却300秒,缩容可以600秒。
设缩容最小实例数,哪怕没流量也留几台保底。
分步缩容:一次只缩一定比例,观察后再缩。
那家电商后来改了缩容策略:保留最小5台实例,缩容冷却设10分钟,每次只缩20%。大促后平稳回落,没出问题。
04 容量预热:提前把枪擦亮
预热是最容易被忽略的环节。很多人以为扩容就是把实例拉起来,拉起来就能接流量。但实际情况是:
Java应用启动要几十秒,JIT预热要几分钟。
缓存没命中,连接池是空的,刚开始处理的请求都会慢。
预热方法:
定时伸缩提前拉起:大促前30分钟把实例扩到位,留足预热时间。
就绪探针(readinessProbe):K8s里配置,让新Pod预热好了再接流量。
负载均衡慢启动:新实例刚加入,只给少量流量,逐步增加。
那家电商预热没做好,扩容的新实例一上来就接全量流量,JVM还没预热,超时率飙升。后来加了慢启动,前30秒只给10%流量,慢慢调到100%,超时率降了80%。
05 一个真实案例:大促扩容三条教训
一个电商客户,大促期间扩容踩了三个坑:
坑一:冷却时间设太短。一波扩容还没稳定,下一波又触发,实例不断创建销毁,监控像心电图。后来把冷却时间从60秒调到了180秒。
坑二:缩容太激进。凌晨流量回落,自动缩容到最低。结果上午又来一波,实例不够,扩容又来不及。缩容冷却时间从120秒改成了600秒,保留最小实例从2台改到5台。
坑三:没有预热。新实例刚启动就接全量流量,响应超时。加了慢启动,前30秒只接20%流量,平稳过渡。
改造后,大促期间系统稳稳扛住,运维负责人说:“以前扩容像救火,现在扩容像排班,提前安排好,到点执行就行。”
写在最后
弹性伸缩不是CPU高了才想加机器,是提前算好什么时候流量要来,提前把枪擦亮。
那家电商的运维负责人后来总结了一个口诀:“指标伸缩被动等,定时伸缩靠预判,预测伸缩更智能。扩容要快缩要慢,预热到位才接单。”
你的大促扩容方案,是等着指标报警再救火,还是提前排好了班?