凌晨两点,我把生产流量切走了一小块:混沌工程到底在赌什么?
凌晨一点四十,值班手机震了一下。不是告警,是我自己定的闹钟。今晚要做一次超时注入,对象是订单服务到库存服务的那条调用链。说实话,手心有点汗。生产环境,谁不怕。
但怕归怕,这事得干。因为线上系统有个很讨厌的脾气:你越不碰它,它越像没问题;真出问题,往往不是单点挂掉,而是一串依赖像多米诺骨牌那样倒。混沌工程干的就是这个——提前把骨牌推一下,看它倒成什么样。
微服务超时故障注入链路监控大屏实拍图
先别急着“搞破坏”,它其实是一场受控实验
很多人听到混沌工程,脑子里蹦出来的是“随机杀进程”“拔网线”“给数据库加延迟”。对,也不对。动作像,目的不一样。
我自己的理解很土:混沌工程是在系统上做可回滚、可观察、有边界的故障实验。关键词不是“故障”,是“实验”。实验得有假设,得有对照组,得知道什么时候停。不然就是事故预演,不是工程。
那次我们写的假设很具体:库存服务响应时间从 80ms 拉到 800ms,订单服务应该在 1.5 秒内触发熔断,降级到缓存库存,用户侧看到“稍后确认”,而不是一直转圈。结果呢?前三十秒还行,第四十秒开始,线程池排队,网关重试放大,监控图上那条 P99 像被人拽着头发往上提。
挺狼狈。但这就是价值。因为如果等到大促真出问题,我们连狼狈的资格都没有。
稳态指标:没有它,实验就是盲人摸象
混沌工程常常被忽略的部分,不是注入工具,是稳态指标。你得先回答一个问题:系统“正常”长什么样?
这话听着废话,实际很要命。我们内部定过三条:订单创建成功率不低于 99.5%,支付回调延迟 P95 不超过 2 秒,核心接口错误率不超过 0.3%。再加一条业务指标:每分钟下单量波动不超过基线 15%。没有这些,注入完你看着日志一片红,也不知道是实验生效还是系统真崩。
稳态指标不是监控大盘的复制品,它得能回答“用户还疼不疼”。技术指标好看,业务指标塌了,照样算失败。反过来,技术指标抖一抖,业务没感觉,实验可能就该继续跑。
还有个细节:指标采样窗口别太短。我们吃过亏。三十秒窗口里错误率没起来,以为没事,结果五分钟后线程池满了。混沌实验像熬汤,火候不到,味道出不来。
Kubernetes节点宕机混沌实验爆炸半径控制示意图
爆炸半径:先划小圈,再谈勇敢
爆炸半径这个词听起来吓人,其实就是“这次实验会影响多少用户、多少机器、多少钱”。
我见过一种很莽的做法:上来就在生产全量注入。勇气可嘉,但这不是工程。我们现在的习惯是三层圈:先单实例,再单可用区小流量,再往后才考虑按比例放量。每层都有止损条件,比如错误率连续两分钟超过阈值,实验自动终止,流量回切。
说个反常识的观察:混沌工程做得越成熟,实验看起来越“不刺激”。因为大部分风险早在小圈子里被掐掉了。真正上线的大实验,反而平平无奇。那些朋友圈里“今晚炸生产”的段子,听听就行。
不过话说回来,小圈子也有盲区。单实例注入发现不了跨可用区的连锁反应。所以爆炸半径不是一成不变,得跟着系统复杂度调。微服务拆得越细,依赖图越像一团毛线,半径的边界就越难画。
它到底用在哪:不是只有大厂才配玩
它到底用在哪:不是只有大厂才配玩
有人觉得混沌工程是平台团队的玩具。其实不是。小团队也能做,只是切口要小。
比如你们就十几台机器,可以先做依赖超时注入:给某个非核心下游加 300ms 延迟,看主流程会不会被拖死。再比如做一次 DNS 解析失败演练,看本地缓存能不能顶住。再土一点,手动把一台节点的磁盘打满,观察告警链路和自动迁移。这些都不需要多复杂的平台。
我们做过一次“伪故障”演练:把某个配置中心的返回故意延迟两秒。结果发现,客户端有个本地缓存过期时间设成了零。零啊,等于每次请求都去问配置中心。平时没事,一延迟就全堵。这个 bug 藏了半年,靠代码 review 根本没看出来。
这就是混沌工程的日常价值:它不一定帮你发现惊天大雷,但经常帮你揪出那些“平时没事、出事要命”的默认配置。
误区与边界:别把它当万能药
一个误区,把它当测试。功能测试验证“对不对”,混沌工程验证“扛不扛得住”。两码事。另一个误区,只注入不观察。没有可观测性,注入就是蒙眼开车。还有,忽略复盘。实验完不写记录,下次还得重新踩坑。
边界也很清楚。混沌工程不适合验证未知业务逻辑,也不适合替代容量规划。你系统本来就没做熔断,注入超时只会得到一堆超时,学不到新东西。还有,别在合规敏感场景里乱来,金融、医疗这些领域,实验审批和回滚预案得厚得像本书。
我自己的底线是:任何一次实验,都必须能在五分钟内回滚。回滚不了,就别叫实验,叫冒险。
凌晨两点二十,实验终止。库存服务延迟撤掉,线程池慢慢回落。值班群里有人发了一句“图好看了”。我回了个“嗯”。然后打开文档,把刚才那四十分钟的监控截图贴进去。下一次,我们打算把爆炸半径再放大一点。不是勇敢,是心里有数了。