【万字长文】一文看懂持续部署按需发布!DevOps部署和发布方法大全 (下)
- 2022-06-24 10:00:00
- 赵卫David
- 转贴:
- 公众号
- 1381
一、支持不同发布方式的技术实现
1.1 特性开关(Feature Toggle/Feature Flag)
利用代码中的特性开关(Feature Toggle/Flag/Switch)来控制发布逻辑,在生产环境中不用编写代码,不用发布新版本,在线上运行时,通过开关,打开或关闭特性。
一般不需要复杂的发布工具和智能负载均衡(Load Balancer)的配合,是一种相对比较低成本和简单的发布方式。
当开关关闭的时候,实际上体现的就是部署,将新版本部署到生产环境的时候,用户不可见,当打开开关的时候,功能对用户可见。所以特性开关很好的支持了将部署和发布解耦。
同时特性开关的各种应用方式可以很好的支持黑启动发布,金丝雀发布,灰度发布,A/B测试等。
如下图所示,特性开关对所有人有效。这是最简单的一种方式,与20年前的License许可证方式类似,例如:
- ToC的例子,所有的用户使用同样的单体软件部署到PC上之后,根据用户的购买的License,打开和关闭某些特性。
- ToB的例子,电信行业,例如华为和中兴卖给中国移动的设备,在部署到客户网路之中后,不用升级软件,只要购买了新的License,相应的特性就会被打开。
还有一种情况是,在用户侧,用户可以自由选择使用开关,打开或关闭某个特性。
1.2 特性分支(Feature Branch)
为了对特性进行物理隔离,以及支持不同的发布方式,在版本控制系统中例如Git上,针对每个特性创建一个特性分支。无需采用特性开关,根据发布需要,对要发布的特性进行代码的合并和集成,这样可以创建多个集成不同特性的新版本,结合其他部署策略,这些新版本部署之后,根据需要使用不同分支版本进行灰度或者A/B测试等。通常使用分支隔离不同版本代码,生产环境是老版本,新的发布使用特性分支对应的新版本;而使用不同特性分支同时发布不同的版本进行A/B测试也不少见。
1.3 抽象分支(Branch By Abstraction)
不采用特性分支方式来隔离大规模软件重构的代码,而是在不创建真实分支的情况下,通过设计手段,将大的架构/重构分解成多个架构切片,迭代增量的实现小的代码变更,逐步完成整体的架构。增量上线的版本,在生产环境,部分功能业务逻辑运行在老代码上,部分功能运行在新版本上。
简单来说,使用设计手段,例如设计模式、面向方面编程AOP(Aspect Object Programming)等,允许在代码层面存在两个版本的代码。
抽象分支通过如下几个步骤进行大规模增量式修改:
- 在你想改变的那部分代码之上创建一个抽象层。
- 对其余部分的代码进行重构,使其使用这个抽象层使用其之下的代码提供的功能。
- 在新的实现代码里实现一些新的类,让其上的抽象层根据需要,选择性的导向旧代码或新增的类上。
- 剔除原有的旧实现。
- 清理,并重复前两步,如果需要,可同时交付你的软件。
- 一旦旧实现完全被代替后,如果你愿意,可以移除那个抽象层。
老马(Martin Fowler)指出,这些步骤也可以变化一下。“在最简单的情况下,你可以创建一个抽象层,然后重构,让所有的代码都调用它,然后再新写一个实现,最后切换一下就行了。但是,还可以将它分开做。比如,不创建整个抽象层,而只是创建将要修改的功能的一个子集,迁移这部分代码,然后再做下一部分(此时新旧代码共存)。
二、Facebook的案例
2.1 Facebook网站持续部署
Facebook网站2003-2017年的分支策略,采用主干开发(Trunk/Master),分支发布(Production/Release)。如下图所示意,每天2-3个小版本,每周一个大版本。开发人员的分支代码每天都会提交代码到主干Master分支,可以说开发人员的特性分支是一个短生命周期的开发分支,可以忽略不计,视作主干开发分支发布。
Facebook网站采用一周的迭代周期,在一周之内频繁发布上线给用户。
同时Facebook使用了一个内部特性开关(Feature Toggles/Flags)系统Gatekeeper,可以在服务端打开和关闭某个特性。新版本是从主干Trunk上开一个分支,名为为latest,代表着最新的发布分支,包含着上周就绪但没有cherry pick摘取到上一个版本代码,即最新的代码代表着所有的代码,一部分代码已经在上个版本发布,一部分是未发布但是就绪完成的代码,然后在周二的时候,因为上一个版本发布分支的名字已经从production改为defunct, prodution名字被释放,就可以将latest分支重新命名为produciton。
总结下,这个发布分支从上周日到周一的时候叫做latest分支,周二到下周一的时候叫做production分支,无论如何改名字,都代表着发布分支,在下面的描述汇中我们统一称之为发布分支。
对于新版本,从周一到周日这个七天里,每天都会选取这个新版要发布的代码,就是下图中主干上字母C带红色框的图标,这个提交被摘选合并到发布分支上,就在发布分支上构成了一个最新发布(紫色五角星代表的版本)但是这个发布仅仅对Facebook员工可见,而最终用户不可见。
从周二开始,每天正式发布给用户1-2次(绿色的五角星,版本号294.0,294.1,294.2 …… 294.6),下周一结束时发布最后一个版本294.7。
经过统计,每个小版本平均包括92行新增或者修改的代码,每个开发人员每周推送到生产环境3.5个软件更新,总体结果是Facebook网站每天可以达到上千次的部署。每个开发人员对自己提交的代码负责,没有单独的测试团队,仅仅要求提交代码之前做代码的同行评审。
Facebook通过黑启动(Dark Launch)阶段,路由一部分真实用户访问后端服务,这时候Facebook的页面与聊天服务器建立连接,查询状态信息,并模拟消息发送,但是使用的是老用户页面,并没有修改界页面显示服务器端返回的消息,这样就可以在全面上线前进行压力测试,模拟新功能带来的影响。
2.2 Facebook移动端App持续部署
2016年3月公开的报告显示,Facebook安卓App采用了一周的迭代,开发测试的周期是一周,而为了上线需要灰度和提交市场,还需要花费一周的时间,所以它的模式是1+1模式,而对于用户来说,每周都可以在应用市场上看到最新的版本。京东商城APP的模式是2+1模式,即开发测试周期是二周,再加上一周的灰度和提交市场时间,京东金融APP的模式将会在2021年对齐京东商城APP的2+1模式。
- 预推送测试(Pre-Push Testing):每个开发人员从主干Master上拉一个本地分支,在本地分支开发,在本地经过单元测试,静态代码扫描,以及部分集成测试之后,进行代码评审。
- 推送中(On push):代码评审之后就启动合并到Master的推送请求,代码在真正的push到master分支之前,触发了自动化测试,包括:单元测试,黄金流程(被大量使用的功能以及核心流程)的冒烟测试,以及简单的新功能测试确保新构建没有问题(build test);所有的自动化测试通过后,本地分支代码就被允许自动合并到master分支,如果出现合并冲突,相关的开发人员就解决冲突。
- 在主干和发布分支上持续测试:每隔几个小时,并行的在主干和发布分支上,持续的运行所有的自动化测试,包括:全面的的build test, 回归测试以及性能测试等。
Facebook使用了黑启动的部署策略,通过特性开关实现黑启动,Facebook的黑启动工具为Gatekeeper,如下图所示:
八、总结
主干开发TBD(Trunk-Based Development)先锋保罗·哈曼特(Paul Hammant)将分支模型映射到发布频率,如下图所示,并且可以看到,特性开关作为一个必不可少的技术,可以很好的支持更频繁的发布。Jez Humble在《精益企业》中引用保罗·哈曼特(Paul Hammant)的部署加速度(Deployment g-forces),每天发布100次采用的是黑启动,蓝绿部署和金丝雀发布,如下图所下,图中将黑启动翻译成了灰度发布。
以上各种部署、发布以及支撑技术,对比总结如下:
分类
方式
简要描述
特点
优势
不足
适用场合
部署
蓝绿部署
滚动部署
黑启动
发布
金丝雀发布
1.也叫金丝雀测试,先发布一台或者小比例服务器或实例,经过流量验证后,再发布给所有用户,目的是线上验证,减少缺陷带来的影响
2.滚动部署的一个特例
3.黑启动的一种实现方式1.对比滚动部署,先部署少量金丝雀机器或实例
2.少量金丝雀先接受流量
3.再全量发布1.能够测试实时生产流量
2.用户体验影响小,发布过程出现问题缺陷等只影响少量用户
3.快速回滚
4.零停机时间1.发布速度慢,因为需要监控金丝雀一段时间
2.需要对监控和可观测性投入
3.需要向后兼容1.对新版本功能或性能缺乏足够信心
2.用户体验要求较高
3.降低全量发布的风险
4.网站式服务端发布应用比较广泛
灰度发布
1.增强性质的滚动部署和金丝雀发布,黑启动的一种实现方式
2.逐步发布开放流量给更大范围的客群,目的是利用客群流量提前发现缺陷1.可以结合使用负载均衡的滚动部署和金丝雀发布
2.可以使用特性开关,结合其他技术,对不同范围客群打开特性开关1.具备金丝雀发布特点
2.在保证基本功能和性能在金丝雀发布被验证之后,再逐步加大放量进一步验证
3.随着客群范围的逐步扩大,问题和缺陷可以得到及时发现和修复1.发布速度慢,因为刻意的逐步放量有个时间过程
2.需要对监控和可观测性投入
3.需要向后兼容1.对新版本质量、功能、性能缺乏足够信心
2.用户体验要求较高
3.降低全量发布的风险
4.移动端APP应用比较广泛
A/B测试
1.针对两个功能A和B,随机选定两组类似的客群,进行对比试验,目的是验证假设,探索业务
2.黑启动的一种实现方式1.测试功能表现和效果如何,例如可用性、受欢迎程度、可见性、转化率、业务指标等等
2.通常应用在前端页面上
3.也可以应用在后台不同策略的对比上1.快速实验能力
2.用户体验影响小
3.可以使用生产流量测试
4.可以做到针对某类特定目标用户进行测试1.设置和搭建复杂度相对较高,有技术门槛
2.由于采样偏差问题导致结果偏差1.用来业务探索
2.有两个或多个方案要进行对比,验证假设
支撑技术
特性开关
通过开关控制新版本和老版本功能,打开开关走新版本代码逻辑,关闭开不按走老版本代码逻辑
1.支持简单的特性开和关
2.结合其他的分流技术,例如不同的用户画像、地域、IP网段、机房等,可以支持A/B测试,灰度发布,金丝雀发布
3.如果具备特性开关技术,可以不使用特性分支,来支持主干开发1.针对不同条件,打开关闭开特性,非常灵活
2.升级和回滚非常快
3.零停机时间1.简单的特性开关是全量切换,有可能打开开关给所有用户带来大量影响
2.复杂特性开关要结合各种分流技术
3.功能开关需要一个配置中心或者开关中心1.需要精细化精准化运营测试
2.支持灰度发布
3.支持A/B测试
特性分支
根据选择的不同特性的分支,产生不同的版本
1.物理上是两个版本,各自有二进制包
2.需要结合不同的部署方式进行部署1.与不同部署方式优势之处一样
2.结合滚动部署,金丝雀发布,支持有限的A/B测试1.与不同部署方式不足之处一样
2.需要维护多个分支和版本1.没有特性开关工具或研发能力
2.简单的版本管理
3.简单的部署管理
抽象分支
不使用特性分支,还能达到创建分支进行重构的同样效果,迭代发布增量的重构
1.没有使用多个分形分支
2.对新代码使用设计手段达成分支效果1.持续发布
2.业务功能交付与重构交付并行
3逐步验证架构的方向和正确性1.成本比一次性完成高
2.整个重构完成时间周期可能会较长
3.技术手段可能较难1.需要较大的架构改动和重构
2.架构风险较大
3.同时还要支持交付业务功能
参考
- 软件发布生命周期:https://en.wikipedia.org/wiki/Software_release_life_cycle
- 持续部署:https://www.scaledagileframework.com/continuous-deployment/
- 按需发布:https://www.scaledagileframework.com/release-on-demand
- 亚马逊平均每11.6秒部署一次:https://www.youtube.com/watch?v=dxk8b9rSKOo
- 《凤凰项目:一个IT运维的传奇故事》:https://item.jd.com/12708994.html
- 《持续交付:发布可靠软件的系统方法》:https://item.jd.com/10843669.html
- 《持续交付2.0:业务引领的DevOps精要》:https://item.jd.com/12512514.html
- 《发布!设计与部署稳定的分布式系统 第2版》:https://item.jd.com/12627801.html
- Facebook大规模快速发布:https://engineering.fb.com/2017/08/31/web/rapid-release-at-massive-scale/,https://www.jianshu.com/p/ef4e9aeac507
- Facebook如何实现大规模快速发布:https://www.infoq.com/news/2017/09/facebook-release-scale/,https://www.zybuluo.com/sambodhi/note/893487
- Facebook的移动端软件的持续部署:https://research.fb.com/wp-content/uploads/2017/01/paper_fse2016-003.pdf
- Facebook移动发布流程:https://www.infoq.com/presentations/Facebook-Release-Process/
- Facebook 的 DevOps 案例研究与相关工具:https://segmentfault.com/a/1190000019236151
- 我们经常聊的金丝雀发布、滚动发布、蓝绿发布到底有什么差别?https://mp.weixin.qq.com/s/MS8wi5t7btxO18Q0rfat4g
- 应用部署和测试战略:https://cloud.google.com/solutions/application-deployment-and-testing-strategies
- 应用部署的六个战略:https://thenewstack.io/deployment-strategies/
- 什么是蓝绿部署:https://digitalvarys.com/what-is-blue-green-deployment/
- 为什么领先公司使用黑启动:https://launchdarkly.com/blog/why-leading-companies-dark-launch/
- Facebook Chat:https://www.facebook.com/note.php?note_id=14218138919
- Facebok黑启动:https://controlaltconstruct.blogspot.com/2019/01/facebook-dark-launching-technique.html
- 黑启动:https://martinfowler.com/bliki/DarkLaunching.html
- Kent Beck响应式设计:https://www.infoq.com/presentations/responsive-design/
- 动物哨兵:https://en.wikipedia.org/wiki/Sentinel_species
- 国内金丝雀:https://en.wikipedia.org/wiki/Domestic_canary
- 金丝雀发布:https://martinfowler.com/bliki/CanaryRelease.html
- 金丝雀测试:https://featureflags.io/canary-testing/
- 蓝绿部署,A/B测试和金丝雀发布:https://blog.christianposta.com/deploy/blue-green-deployments-a-b-testing-and-canary-releases/
- A/B测试:https://en.wikipedia.org/wiki/A/B_testing
- A/B测试知识点总结:https://www.jianshu.com/p/c5832ad60575
- A/B测试实践全总结:http://www.woshipm.com/pmd/699804.html
- A/B测试:https://learn.growthhackers.com.cn/skills/ab/
- 多变量测试与A/B测试:https://www.optimizely.com/optimization-glossary/multivariate-test-vs-ab-test/
- 特性开关:https://martinfowler.com/articles/feature-toggles.html
- 部署新版本:特性开关还是猪增量发布?:https://opensource.com/article/18/2/feature-flags-ring-deployment-model
- 特性开关驱动开发:https://blog.launchdarkly.com/feature-flag-driven-development/
- 探索如何在生产环境逐步地为部分或者全部用户启用特性:https://docs.microsoft.com/en-us/azure/devops/migrate/phase-features-with-feature-flags?view=azure-devops
- 特性开关使用场景:https://featureflags.io/feature-flag-uses/
- 利用抽象分支做增量式大规模软件改造:http://www.continuousdelivery.info/index.php/2013/01/04/branch_by_abstraction/
- 老马的抽象分支:https://martinfowler.com/bliki/BranchByAbstraction.html
- Facebook主干开发:https://paulhammant.com/2013/03/13/facebook-tbd-take-2/
联系人: | 阿道 |
---|---|
电话: | 17762006160 |
地址: | 青岛市黄岛区井冈山路157号中南金石国际广场A座3202室 |