写点什么

服务变更如何做到高可用?

  • 2019-08-07
  • 本文字数:3527 字

    阅读完需:约 12 分钟

服务变更如何做到高可用?

近期,Cloudflare在更新 WAF 配置规则时,因其中一个规则包含了正则表达式,导致 Cloudflare 全球机器上的 CPU 峰值使用率达到 100%,在最糟糕的时候,流量下降了 82%,对整个互联网都产生了明显的影响。


因此,变更的定义,不仅仅是狭义的上线新版本代码,也应该包含配置变更,数据变更,操作系统变更,网络变更,基础设施变更等方面。变更是运维人员的主要工作内容,同时也是导致服务故障的主要原因。据 Google SRE 统计,线上 70%的故障都是由某种变更而触发的。

服务变更的关键点

部署清单

部署清单主要是管理部署期间的整个生命流程,通过将各个阶段的各个步骤进行罗列和长期维护,从而逐步形成针对特定变更场景的说明手册。


如果只是升级一台服务器的二进制代码,需要部署清单吗?答案是肯定的。不能把二进制代码变更等同于二进制文件替换,在替换动作之外,有很多的工作内容,仅仅是更新完毕以后,就需要考虑如下问题:


  • 程序是否正常启动

  • 日志是否存在异常信息

  • 服务功能是否正常

  • 服务性能是否符合预期

  • 服务关键指标是否异常


对于多模块,多系统,多团队配合的变更操作,如果没有一份事前经过充分验证的部署清单,谁在什么时候应该做什么事情,准入条件是什么,交付标准是什么,有哪些操作禁忌和注意事项,那这种复杂变更的结果就只能靠运气了。


随着运维自动化水平的提升,部署清单并不会消失,而是在载体上有所不同,从早期的纸质上线单,到现在内置于部署系统中,实现了更好的经验传承,校验完善,流程管控,信息分享等。

灰度发布

绝大部分服务,都不应该由单个实例组成。那么,在变更的时候,就应该避免一次性升级所有实例,而应该分批次的逐步升级,并在每个批次间预留一定的时间间隔对上一批次进行观察和评估,从而决定是否继续进行升级,以此来保障变更的质量。


以 Google 为例,其灰度发布的比例,从 0.1%开始,每 24 小时增长 10 倍推进,从 0.1%-> 1% -> 10% -> 100% (详见 Google SRE 中文版 162 页),并且灰度的初始比例一定不可以超过服务整体的冗余度。同时,在对服务进行变更操作的期间,需要将流量摘除,避免对线上产生影响,变更操作完毕后,方可引入灰度流量进行验证。


在灰度阶段,有针对性的选择灰度流量,尽可能完整的覆盖各类业务场景和用户类型,并通过流量调度形成局部热点,对服务的性能进行验证,避免全量上线可能出现的性能下降。

快速回滚

变更操作一定要有回滚预案,并能够快速回滚!日常的变更操作,只要有备份,大多数情况都可以进行回滚。那些无法进行回滚的,一般都是重大变更,这时候,等着你的基本上就是直接在线上调试并修 bug 以及超长的停机时间和大批的脏数据了。


不同公司对待回滚的态度不同,和其背后的专业能力有很大关系,因此不能盲从。如果对所有的回滚事件不加甄别的进行追责,那么导致的后果就是对于非核心故障,研发坚决不进行回滚操作导致带伤上阵,或者说将回滚美其名曰快速迭代。

功能开关

比回滚更高效的方案是功能开关,在发现新功能上线有问题后,可以通过功能开关立即关闭该功能,从而起到更快速的止损效果。可以想象一个场景,一次上线后,发现 10 个功能里面有 1 个功能异常,且引发了部分脏数据,因为还需要确保其余 9 个功能正常,因此不能全并发回滚,只能按照预置的并发度进行回滚,那么回滚耗时就会较长,这时候,如果有功能开关,那情况就大不一样了。

线下测试

既然线上有了变更保障能力,那为啥还要在线下费劲搞集成测试呢,直接在线上测不就行了吗?我们假设这个观点是正确的,那么所有未经测试的代码全部推送到线上开始灰度,在灰度阶段去发现各种问题,然后回滚,修复后继续上线。但灰度的流量,也是真实的用户,怎么能够拿用户的真实流量做这样的事情呢。因此,线下测试还是非常重要的环节,通过线下测试,将 80%以上的基本问题拦截在线下环节,在灰度环节,更多的去解决线下环境无法覆盖的场景。同时,参照 Chaos Monkey,以随机的方式对线下环境以及灰度环境进行破坏性验证,让服务具备应对各种典型故障场景的容错能力。

效果检查

服务变更后,需要有一系列的基于部署清单管理的效果检查的内容,例如前面提到的程序是否正常启动,功能是否正常,性能是否正常,以及本次调整的内容是否符合预期,通过对变更的效果进行验证,才能最终确认本次变更是否正确。同时,针对服务相关的全局核心指标的监控,在变更期间,既不应该出现异常,更不能被随意屏蔽掉。

时间窗口

早期,Facebook 的交付工程团队,会在每个工作日进行一次非关键性更新,而重大更新则每周进行一次,通常在周二下午进行。这里就体现了时间窗口的概念,时间窗口主要是用来降低变更导致的影响,常见的时间窗口有如下建议:


  • 尽量避免节前做变更,即使是 BAT 和运营商,对于全年重要的节假日,往往会提前数周停止业务的非必要性变更,或者是将自动流程转为审批流程;

  • 尽量避免在业务每天的高峰期做变更,例如很多网络切割都是选择凌晨进行操作,就是避免对业务产生影响;

  • 尽量避免在下班前尤其是周五下班前做变更,提前通告并全员值守的除外;

  • 尽量避免在非工作时间(包括周末和节假日)进行自动部署。

隔离

如果服务是分组部署(多 AZ 部署、多 Region 部署),且分组间能够做到尽量避免服务间的交互和基础设施共享,那么在变更中,就需要利用该特性,对分组进行逐一升级和观察,避免问题发生扩散,在出现问题的时候,通过流量调度即可快速摘掉流量止损。

通告

任何的变更,都需要事前进行通告,告知相关的上下游团队,变更时间,变更内容,可能的影响,应急联系人等,并在变更期间的各个阶段,进行通告。同时,也应该将变更信息录入到统一的系统中,便于相关上下游订阅。这里需要注意的是,在通告系统中,各个业务方的联系方式应该基于邮件组等群组方式,避免直接写入具体的人员列表,从而因人员调整导致通告失效。

避免手工操作

对于低频非标准化的场景,在部署清单中可能会这样描述:”请将存放在 XX 地方的操作系统镜像文件集,拷贝到线上某一批服务器的 XX 路径下“。那为什么这种常规的文件替换不通过部署系统进行呢,是因为操作系统镜像文件体积太大,无法存放在版本库当中,且主流操作系统镜像每年变更至多两次,因此,大家都觉得手工操作一下就好了。但这里面存在一些高风险的地方:


  • 不对网络传输进行限速,可能会在短时间内导致服务器 IO 和网卡使用率较高,进而影响线上的业务;

  • 如果是替换操作,且直接对线上文件进行替换,因为文件体积较大,会导致在替换期间,用户获取到不完整的文件;

  • 文件传输完毕后,所有服务器上的文件是否完整,是否正确,没有校验方案。


从上述的简单 case 可知,即使简单如文件传输这样的操作,如果没有运维系统的支持而手工进行,也可能导致较为严重的线上故障。同时,也不建议为这类场景编写一次性的脚本,因为这类脚本本质上和手工操作并无区别,上述的风险并不会因为你临时写一个脚本而消失,还是应该回归正途,通过部署系统、传输系统或者其他的运维自动化平台来解决。

服务变更的最佳实践

蓝绿部署

本文以蓝绿部署为基础,介绍服务变更的最佳实践。



截图简要说明:将系统按照 AZ 的维度,独立部署了 4 组,分别是 AZ1、AZ2、Z3 和 AZ4,这四组完全一致,基于隔离的思路,四个分组间,尽量避免了服务间的交互和基础设施共享。


考虑到线上环境的复杂度,以及天然存在一定的冗余度,因此每次仅升级一个 AZ 分组。在第一个分组 AZ1 的时候,会进行较为详细的验证,除去常规的自动化检查外,还会有测试人员的手工效果检查,以此确保变更的质量。其余 AZ 因为变更内容一致,因此不会有测试人员的接入,仅保留自动化检查。


如果变更存在问题,因选择的 AZ1 是明确小于冗余度的,因此仅需要摘除流量后,再进行回滚,部分时候,如果研发要求短暂保留现场,也可以满足其要求。


部署系统

部署系统应该将变更的关键点内嵌到部署系统中,不断完善,让其成为变更流程无法逾越的环节,从而更好的保证变更质量。一个部署系统在做好单机部署工作的同时,也应该满足如下业务侧的需求:


  • 提供部署清单功能,并具备自动化的检查能力,阶段性进展通告的能力;

  • 提供版本管理功能,常规变更(二进制代码和配置)必须全部基于版本库进行;

  • 提供快速回滚功能,能够帮助业务快速回滚到上一个稳定版本,并能够按照业务上下游编排顺序进行回滚;

  • 提供时间窗口功能,默认不能够在业务定义的黑名单时间点上线;

  • 提供备份功能,每次变更都需要将可能影响到的内容进行单机备份,便于快速回滚,默认是需要将上次的发布包进行全量备份尽量排除掉日志;

  • 提供灰度发布功能,能够定义分组间和分组内的并发度,分组变更的暂停时长等;

  • 提供效果检查功能,自动化的对业务进行预定义的各类检查并和部署动作联动,如暂停变更,继续变更以及调整灰度的比例;

  • 提供编排功能,满足多模块的联合上线。


2019-08-07 08:0840134

评论 6 条评论

发布
用户头像
线下测试的顺序要往前提一下,放在第二位会更合理一些。
2020-04-08 10:03
回复
用户头像
回滚也是变更,既然是变更,就需要遵循灰度的原则,因此,即使是服务故障后的回滚,也不能全量回滚,否则会引发雪崩,当然,如果流量摘除后,整个系统完全不接流量了,那么全量回滚可能才可以进行。
2019-11-26 10:11
回复
用户头像
还应该在增加合规性检查
2019-09-18 20:11
回复
用户头像
参考文章:来自 Google 的高可用架构理念与实践
2019-09-04 11:56
回复
用户头像
参考文章:
来自 Netflix 的系统高可用建议 :https://www.infoq.cn/article/tips-for-high-availability
2019-09-04 11:48
回复
用户头像
顶大牛!
2019-08-08 10:58
回复
没有更多了
发现更多内容

等待风起——京东.Vision项目参与实录分享

京东零售技术

Vision pro 京东.vision

阿里巴巴中国站商品搜索API返回值解析与实战

技术冰糖葫芦

api 网关 API Gateway API 测试 API 策略 pinduoduo API

精准学:用一根垂直大模型支柱,撑起教育普惠的未来

脑极体

AI

游戏直播平台开发如何避免安全漏洞?这里有一份解决方案!

软件开发-梦幻运营部

C++创建与调用dll动态链接库(MinGW64 Dev-C++)

快乐非自愿限量之名

从管控角度谈慢SQL治理

不思jo

京东鸿蒙上线前瞻——使用 Taro 打造高性能原生应用

京东零售技术

鸿蒙

如何使用 StarRocks 管理和优化数据湖中的数据?

镜舟科技

数据湖 数据处理 分布式架构 StarRocks

合同管理软件分析:主流的10款哪个好?

爱吃小舅的鱼

系统开发

ICE 8月各项板块盈利报告,人工智能与高频交易驱动稳定收益

科技热闻

探索最佳多人协作软件,优化团队流程

爱吃小舅的鱼

协同办公软件 团队协作工具 协作工具

开发者必备的 4 大类 AI 工具盘点,错过你就亏大了!

伤感汤姆布利柏

AI+医疗:营销机遇洞察2024

易观分析

医疗 人工智能’

区块链趣步模式DAPP系统开发部署搭建

V\TG【ch3nguang】

趣步模式DAPP系统开发

Hugging Face 的应用

霍格沃兹测试开发学社

纯CSS实现海浪文字效果

南城FE

CSS 前端 动画

C++ 之 perf+火焰图分析与调试

芯动大师

perf C++ 火焰图

三分钟带你看懂,低代码开发赋能办公方式转变

不在线第一只蜗牛

低代码

一文读懂企业治理转型助力数字经济和低代码发展

快乐非自愿限量之名

低代码

Java 内部类的使用场合介绍

秃头小帅oi

避坑指南!细说Python自动化办公的5大缺点

程序员晚枫

Python 自动化办公

SyncBird Pro for Mac(iPhone文件管理器) v4.1.1激活版

Rose

大奖收割机!望繁信科技荣获年度技术创新和应用品牌奖

望繁信科技

数字化转型 流程挖掘 流程资产 流程智能

收藏!打造高质量技术文章的8个技巧

京东零售技术

写作 企业号9月PK榜

精准电商营销:基于京东商品详情API返回值的数据分析

技术冰糖葫芦

api 网关 API Gateway API 测试 API 策略 pinduoduo API

百年码头遇见数智化:华为和天津港解锁新质生产力

Alter

由点到面,英特尔与腾讯持续深耕云、网络、存储等领域

E科讯

《代码整洁之道》-大师眼中的整洁代码是什么样

京东零售技术

后端 代码

阿里巴巴中国站1688商品搜索API返回值深度解析与实战应用

代码忍者

API 测试 API 策略

构建Web3社交平台:DeBox式DApp开发全攻略

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 NFT开发 代币开发

Reflection 70B 遭质疑基模为 Llama 3;Replit Agent:编程 0 基础适用丨 RTE 开发者日报

声网

服务变更如何做到高可用?_软件工程_焦振清_InfoQ精选文章