饿了么技术往事(中)( 四 )


在这个过程中 , 也做了不少尝试 , 比如 , 为了提高 alpha/beta 这两个测试环境的基础设施交付效率 , 有过一段时间基于 slack 的 ChatOps 实践 , 工程师都比较欢迎;还有过 Infrastructure as Code 和 GitOps 的实践 , 很可惜当时各方面条件和时机都不够成熟 , 没有持续推广 。
体会和教训——DevOps
alpha 和 beta 环境:
工程师在开发机上自测是不是就可以了 , “在我机器上是好的”这句话估计开发工程师都说过或者听过 , 在开发阶段提供alpha环境 , 目的就是为了开发、测试、生产环境的尽量接近 , 避免由于开发、测试、生产三个阶段由于环境差异巨大带来的问题 。 解决不了“在我机器上是好的”这个问题 , 没有办法大规模顺利上云 。 工程师自己的电脑 , 某种程度上是一台“mommy server” , 上面运行着需要的一切环境 , 而且每个工程师的祖传环境还不一样 , 这类环境在生产上是不可复制的 。
Build & Release:
怎么做到高质量快速交付 , 保证系统的稳定?
在快速迭代的同时 , 做到快速试错、快速纠错、快速回退 。 需要发布系统做到每个编译的版本、每次发布的版本 , 像代码一样 , 可回溯可跟踪 。 关键在于build和release是immutable的
首先 , build和release有唯一的ID , 才可追溯 , 可回滚;
其次 , 是配置分离 , 把和环境(dev/test/product)相关的config从代码中剥离开来 , 否则系统很难迁移 , 更不用说大规模上云 。 第一反应可能是 , 把和环境相关的config写在xml或者yaml文件就可以了 , 但是 , 这些文件也是代码 。
类似的 , 将这些随环境变化的config写在发布流水线的脚本里面 , 都不是彻底分离的方式 。 因为发布环境会发生变化 , 可能将来有更多的测试环境、更多的数据中心、每个数据中心里面可能还有多泳道 。
因此 , 要做到“build once, deploy many times/every where” , config要存储在环境的上下文中 , 比如开发、测试、生产环境各自有一个配置中心 , 线上系统拉起的时候 , 先从配置中心拉取配置信息 。 要衡量环境相关的config和代码是否已经分离 , 看看能不能开源就知道了(抛开价值和代码质量不谈) 。
OPS
接触过传统的运维工程师都知道 , 这是一群责任心极强的人(删库跑路 , 铲平数据中心的事情是不可能干出来的 , 虽然有能力……) , 他们维护着系统的底线 , 第一次517大促事故的时候 , 我们靠运维工程师救了大家一命 。
但是 , 即使有操作的SOP , 只要是人 , 执行重复任务的次数足够多 , 总会犯错 。 而每个资深的运维工程师 , 都有自己祖传的脚本 , 一夫当关万夫莫开 , 但是休假就麻烦了 , 特别是在高铁上信号不好的时候……最佳实践→ SOP → 脚本 → 自动化工具产品 , 沿着这个路径迭代似乎不可避免 。
传统的运维工程师角色的演进方向 , 一个是为云上的IaaS/PaaS服务 , 对操作系统和底层硬件有着丰富经验的 , 还是运维工程师 , 他们当中开发能力强的 , 转型SRE , 对运维产品理解深的 , 可以选择 Technical Product Manager 的角色 , 为云上运维相关平台产品提供解决方案 , 或者凭借丰富的云上系统落地实施经验 , 为各上云企业提供实施方案 。
另一个方向 , 由于合规和其他原因 , 还有部分没有上云的企业 , 依然需要基础设施运维工程师 。 随着云逐渐变成和水电煤一样的社会基础设施 , 运维工程师只写操作系统脚本、实施部署的时代已经渐行渐远了 。
架构的历次演进 , 和几次事故或者险些酿成事故的“冒烟”事件 , 有着很大的关系:
交易系统崩溃的“饿死了”事故 , 我们开始分离关键路径和非关键路径 , 建设了非关键路径的降级能力 。 故障应急响应常规三板斧:重启、回滚、降级 , 至此完备 。