一些历史
1895年,英国生理学家John Scott Haldane提出,小型恒温动物的呼吸交换比人类更快,矿井中的一氧化碳等有毒气体或甲烷等窒息性气体会先影响它们。同样的一氧化碳浓度下,老鼠会在几分钟内受到一氧化碳的影响,而人类需要 20 倍的时间。于是自1896年左右,老鼠开始被用作预警井下有毒气体的工具。
一段时间后,人们发现金丝雀这种生物对于有毒气体更加敏感。最早的记录是在1900年:一些矿井开始把金丝雀作为井下有毒气体的探测工具,用于防止如二氧化碳、一氧化碳、甲烷等能够对生命造成威胁的气体。
金丝雀的使用成本明显高于老鼠,为了能重复使用金丝雀,人们发明了一个用于金丝雀毒气探测的专用笼。这种笼子可以主动充氧,前方设有一个通气孔,通气孔可以通过密闭窗进行开启和关闭。需要金丝雀进行预警时,先把通气孔打开,如果笼子中的金丝雀被毒气毒晕了,那就关闭通气孔并让笼子充满氧气。如果金丝雀没有被毒死,就有可能活过来并被再次使用。
气体检测的现代时代开始于1926年,随着越来越精密的有毒气体探测仪被发明并投用,这种用生命来探测的方式开始逐步退出历史舞台。1986年,英国和美国正式停止使用金丝雀来作为井下气体探测的牺牲品。
回到持续部署的定义,金丝雀部署(也就是更为常用的灰色部署)的目标、逻辑与使用金丝雀来进行预警非常类似(通过开关通气孔/流量的方式来控制危害与恢复能力),也许人们也希望能纪念一下在 20 世纪为矿工献出生命的金色小鸟们,所以这种方式被冠上了金丝雀的名称。
了解完名字的来历,我们开始来了解一下金丝雀部署到底是什么样的。
基本定义
金丝雀部署指在将完成更改的代码推广到整个服务集群并使其对所有人可用之前,先推广到一小部分用户进行测试,并在测试过程中持续观测被测对象各个维度的状态,以验证新版本的功能性、可用性、稳定性。等验证结果达到期望目标,便可逐步将新的版本部署到更多服务器,使更多用户使用到它。
优势
零下线时间与快速回滚:
在一系列的相关验证和测试之后,如果新版本的软件被认为不合适,则很容易回滚和控制影响范围。
真实场景下的测试:
由于是直接将新版本部署到生产环境进行测试,所以能够通过真实流量对新版本进行针对性的验证。当然,需要对流量和用户进行限制,来控制验证的范围和影响面。
较低的基础设施成本:
因为金丝雀部署策略是通过一定规则,按规则对的请求进行要求的分流或路由(例如:用户名、地区、年龄、随机等),所以只需要少量额外的基础设施,就可以达到验证的效果。对比而言,蓝绿部署需要准备与生产环境同样的一套基础设施,部署成本显然会高很多。
灵活地按需进行验证相关版本、功能的正确性:
可以根据不同的特征和标识,对请求的流量进行多维度分流和路由,以达到不同粒度不同特征的灵活验证。
不是银弹
虽然金丝雀部署能够为大家的部署提供强力的支持和帮助。但是,软件工程中是没有银弹的(指没有任何一项技术或方法可以让软件工程的生产力在十年内提高十倍,出自Fred Brooks于1987年发表的关于软件工程的经典论文)。金丝雀部署在很多场景下也需要谨慎使用:
严格不允许出错的系统,例如:医疗系统、消防系统等。
需要部署的数据结构已经无法向下兼容当前版本的数据结构:
虽然阿里云的 MDS 能够提供分流影子数据库的能力,但正式用户使用仍会影响实际的数据和行为体验。在此情形下,仅限于测试人员或内部用户的部署才能发挥金丝雀部署的作用。
非自动化的金丝雀部署,既耗时又容易出现错误,应尽可能使用自动化的方式,而不是去手动维护分流策略和逻辑。
其他很多对生产环境要求严格的场景,均不建议使用。
接下来,让我们换个思维来看看一些细枝末节的讨论。
金丝雀发布 or 金丝雀部署?
在交流和口语中,大家习惯于将发布和部署混用。常常会看到类似于将蓝绿部署、灰度发布(比起金丝雀大家更愿意用灰度)、滚动发布等名词被列举到一起,以表示他们都是发布版本的一些不同的方法。
下面我们开始来咬文嚼字。
发布:
[issue;release;deliver;distribute] 宣布,发表
例句:向全国发布新闻
部署:
(1) [disposition;deployment]∶处理;料理
例句:炮兵的部署已标明在这张地图上
(2) [arrange;lay out]∶安排
例句:部署计划
根据上面的两个词典释义,我是这样理解发布和部署的:
发布广义上是指思想、观点、文章和意见等通过报纸、书刊、网络或者公众演讲等文字和演讲的形式公之于众,向外界传输消息的一种过程。放在计算机这个范畴中时,它是一种将某个特定的软件放到大家能接触到的一些地方,被动的让大家去更新或者同步。比如:我把软件的某个版本打包发布了。
部署广义上是指安排或执行人力、计划、任务等。放到计算机这个范畴,指将特定软件安装或更新到对应的环境中,使其可以为用户提供服务。比如:我把新版本部署到测试环境了,你测试一下。
根据上面的解释,笔者认为更准确的措辞应是金丝雀部署(Canary Deployment)。
与 A/B 测试的关系
刚开始对金丝雀部署了解时,发现许多地方将 A/B 测试与金丝雀部署混为一谈,甚至有直接将这它们两个当成一个东西来对待。实际上,在深入了解后,会发现它们之前确实是有联系,不过还没达到可以画上等号的程度。
相同之处
他们之间的网络流量处理逻辑非常相似,都是通过流量不同特征来决定,对流量进行服务的版本。
金丝雀部署可用作实现A/B 测试的技术基础的一部分;但是不要将它们避免混为一谈。
不同之处
他们两者的目的是完全不同的,金丝雀部署被用来检测问题和回归功能,A/B 测试是一种来用来测试业务设计假设的方法。从二者的目标出发,他们测试的和观测的方法是不一样的。
金丝雀部署的通常是使用偏技术侧观测工具(APM、日志监控等)。技术/开发人员会对需要部署的新版本服务进行观测。当观测结果与预期相符,则技术人员可以进一步操作。否则,需要先解决问题,再部署和观测,直到能够达到预期,再进行进一步下一步操作。
如果我们用同样的方式和工具来希望对业务观测,是无法得到准确结果的。甚至观测的人员职能都不同。一般情况下,A/B 测试对观测部分需要预先的观测数据收集埋点。接着,对收集到的业务数据进行整理和统计,最终得出相关的数据分析结果和统计结果,以提供给业务人员对新业务进行分析和判断。
最后,从更时间的角度来说,业务人员在收集足够的数据以证明A/B 测试的显着性可能需要数天时间,而技术人员希望金丝雀部署在几分钟或几小时内完成。
聊了这么多实现无关的话题,接下来让我们来一起看看,实现金丝雀部署有哪些办法吧。
实现
实现结构
金丝雀部署的关键点有如下几点:
网络流量分流
分流策略管理
多应用间分流传递策略
数据兼容性处理
由上图关键点我们可以通过下图了解的更加明确:
下面我们从流程入手,看看金丝雀部署具体的执行过程是什么样的。
具体流程
从流程入手,这样很容易就能了解到金丝雀部署在不同阶段,呈现出什么样的特征,提供了什么样的能力等。
正常阶段: 当前环境中只有 1-n 个版本已验证版本, 为所有的用户提供服务。
验证阶段:当前环境存在 2 到 n 个版本, 其中有一个已验证版本, 为大部分用户提供相对稳定服务, 剩下的 1 到 n-1 版本为需验证版本, 为特定用户(某些场景下随机挑选)提供相对不稳定服务。同时,持续观需验证版本运行情况,以判断该版本是需要进行部署,还是进行其他处理。
部署阶段: 某个需验证版本通过验证后,此需验证版本将被部署至计划的服务集群占比。如果,还需进一步测试,则又回到验证期进行验证.直至,需验证版本部署占比达到最终需要。往往会使用滚动部署的方式进行部署。
实现方式
这里提到的主要都是服务器端的实现方式。
根据不同的实现方式可以将其分为下列几种类型:
基础设施实现(IAAS):比如通过阿里云 MDS 工具实现;
平台实现(PAAS):通过 K8S 的 Ingress 组件或 Istio 来实现;
通过 Nginx 等中间件实现:直接在 Nginx 中通过脚本控制流量转发规则;
...
由于金丝雀部署本身的实现细节与应用场景具有紧耦合特性,具体的实现方法就不在这里展开了,希望本次抛砖引玉能带来大家对金丝雀部署更多的思考和讨论。
最后
20 世纪的某一天,昏暗的狭窄的矿井中。头戴矿灯的矿工一手提着一个笼子,另一手并着脚努力的往前爬行,汗水裹着黑色的粉末在脸上往下流淌。 美丽的鸟儿在摇摇晃晃的笼子中努力的保持着平衡,不知道迎接他侥幸逃脱后的阳光还是窒息的毒气。
网友评论