在甲方管系统的这五六年里,我经历过一次想起来就脸红的一次生产事故:测试环境的回调地址错配进了生产环境里,一笔测试订单触发了一条真实的短信通知,客户大半夜收到了一条莫名其妙的验证码,第二天一早就把投诉捅到了老板那里。那次事故之后,我们把多环境配置管理从头到尾彻底整改了一遍,一个环节都没有放过。这一篇就把当初整改的思路和方案完整地讲出来:环境怎么分、配置怎么隔离、发布怎么防呆,一节一节地展开,每节都配着踩过的坑讲,是一套拿来就能直接照着抄的成套做法。
这次整改从划地盘开始:到底要几套环境、每个环境管什么,先白纸黑字定下来再说,省得后面扯皮都扯不清,这一步排在任何技术方案前面。
先看环境怎么分:不是越多越好,也不是两套就能凑合的。
整改的头一步是把环境数量和各自的地盘定下来。我们一共定下了四套:开发环境给开发同事做日常的调试用,数据可以随便造、随便删,不用心疼;测试环境做功能验收,数据交由测试团队来维护;预发环境对齐生产配置,只差一个真实的外部渠道对接;生产环境服务真实用户,任何改动一律走发布流程。四套环境各管各的:权限分开、数据分开、域名也分开,谁也不能越界去串门,各自安生。这套划分定下来之后,新同事入职看一眼文档就明白哪个环境能干什么。
分完了环境,再给每个环境都戴上一张"工牌",走到哪儿都认得出来。
每一套环境都有一个独立的环境标识,从应用一启动就注入进去,跟着跑完全程,日志、监控、告警全都带着这个标识。以前排查问题的时候,经常分不清楚一条报错日志到底来自测试环境还是生产环境,只能来回地猜、挨个环境翻。有了标识之后,日志一拉出来就知道是谁家的,排查的时间省下来一大截,效率的提升实打实。
地盘划好了,再看配置怎么隔:一共三道防线,一道比一道严实,层层设防。
头一道防线管的是文件层面的隔离,先把配置文件各归各家。
配置文件按环境独立存放,目录的结构大致长这样:
common: # 各环境共享的默认配置
log_level: info
page_size: 20
test: # 测试环境覆盖项
db_host: 10.0.1.10
sms_mode: mock
prod: # 生产环境覆盖项
db_host: db-prod.internal
sms_mode: real规则定的是:公共的配置放 common,环境的差异只写覆盖项,加载的时候按 common 打底、环境项覆盖的顺序合并。这样一份配置改了公共部分,四个环境就同时生效;改了环境项,就只影响对应的那一个环境,互不干扰。这样改公共配置不用挨个环境复制粘贴,改环境差异也不用提心吊胆,维护起来一切清清爽爽、明明白白。
第二道防线管的是密钥:仓库里一个真实的密钥都不许存在,查到就是踩红线。
数据库密码、第三方密钥类敏感信息,一律不进配置文件、也不进代码仓库。我们接入了统一的配置中心,敏感项都在运行时从配置中心拉取,代码仓库里只留下一个占位符。权限按环境分成了不同的租户,测试环境的密钥连生产的门都摸不着,物理上就够不着。密钥这一层隔离做扎实了,仓库就算被人翻个底朝天,也掏不出任何能碰生产的东西。有一次外部安全审计翻遍了整个仓库,一个生产密钥都没找到,事实证明这一条路线走对了。
第三道防线管的是副作用:能对外产生真实影响的渠道,全部加上开关,一视同仁。
短信、支付、消息推送这一类有真实副作用的外部渠道,全部都加上了模式开关,一个都不落。测试环境一律走 mock 模式:短信只写进日志里不发出去,支付只走沙箱通道。开头说的那次事故,根因就是没有开关隔离这道闸门,测试流量直接打到了真实的短信通道上。开关加上之后,这一类事故从根上就断绝了,两年多再没有发生过一次。每次新接一个外部渠道,同事的头一个动作就是先问开关加好了没有,这已经成了习惯。
静态的隔离之外,动态的发布环节也要防住:用流程和工具把人为失误挡在门外面。
防呆的头一招:机器核对,替人盯住每一处配置差异,连眼都不会眨一下。
发布时的高发事故就是"带错配置上线"。我们专门做了发布前的自动核对:脚本自动比对测试与预发之间的配置差异,逐项列出来,经过人工逐项确认之后才允许打包。有一次比对出来,预发环境多了一个调试开关没关,当场就把它拦了下来,避免了一次线上事故。机器比人可靠的地方就在这里:它不会累,也不会想当然,更不会因为赶时间就放水。核对脚本上线之后,带错配置上线这种老毛病就再没犯过。
防呆的第二招:两个人盯住同一道变更,四只眼睛总归胜过两只。
生产环境里的配置变更,一律走双人复核:一个人动手改,另一个人在旁边看,两个人都确认了才让生效。听上去有点繁琐,实际每次也就多花两分钟。这套流程换来的东西很实在,一点不虚。这两年里有三次配置错误都在复核这一环节被拦下,没有一次漏到线上去。制度的价值不在平时,而在防着那个万一上。多花的那两分钟,买的其实就是一份安心。
防呆的第三招:所有改动留痕,出了事能一路查到源头,想赖也赖不掉,想丢也丢不了。
所有的配置变更都有完整记录:谁改的、什么时间改的、改了哪一项、改动前后的值各自是什么,记得一清二楚。出了问题不用开会互相猜,把记录一拉出来,几分钟就能定位到源头。这套完整的记录还帮我们应付过一次外部审计,审计员要看的材料一样都不缺,当场就给我们通过了。
本地做好的隔离,上了云之后还要再升级一遍,新的问题也跟着来了。
上云的头一件事:把环境之间的墙砌得更高、更厚,别给任何失误留门缝。
上了云之后,环境隔离这件事多了一层选择:我们用的是账号级的隔离,测试和生产放在两个不同的云账号里,网络这扇门天然隔开,能配错的余地就更小了。也有些团队用同一个账号下的不同资源组,成本低一些,但隔离的强度就跟着打了折扣。我们给自己定下的原则是:规模小的时候怎么弄都还行,可一旦涉及真实资金和客户数据,隔离就要往严里做,宁可为此多花上一点钱,这笔账怎么算都算得过来。
云上的第二个问题:配置会被人悄悄地改掉。
配置漂移是云上环境的新问题:有人直接在控制台上手改了一项配置,代码仓库里却没有留下记录,时间一长,两边就对不上了。我们给系统配了每日巡检任务,自动比对运行中的配置和仓库里的配置,天天不落。一旦发现漂移,当天报警、当天就纠正。巡检上线后的头一个月就抓到了七处漂移,全都是控制台手改留下的,一处一处地全部清理了回去。
末了说一点个人的体会,也算给这一篇收个尾。
多环境配置管理这件事,技术上的难度其实不算高,难就难在纪律这两个字上。四套环境、三道防线、双人复核,每一条单独看都是笨办法,但组合到一起,就是让人想错都难。做完这一整套整改,我们团队两年里没再出过一次环境事故,半夜的告警电话也跟着少了一大截。系统稳定这件事,从来就没有一招制敌的说法,全都是靠这些不起眼的规矩一点一点堆出来的,别嫌它们笨,笨办法就是扛用。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。