应用发布

在项目迭代的过程中,不可避免需要进行项目上线。
上线对应着部署或者重新部署,部署对应着修改,修改则意味着风险。
目前有很多用于部署的技术,有的简单,有的复杂,有的需要停机,有的不需要停机即可完成部署。
这里对目前常用的部署方案做一个简单的总结。
1. 蛮力发布
2. 蓝绿发布
3. 灰度发布
4. 滚动发布
 
1. 蛮力发布
如下图所示,这种发布方式比较简单粗暴,主要靠手工完成,先将老版本 V1 全部下掉,再将新版本发到机器上去。
这种方式会中断服务(停机),在开发测试环境是可行的,但对于生产环境,会直接造成用户不可用,一般不建议。
 
优势:
• 操作简单
• 成本低
 
不足:
• 迭代过程中服务中断, 用户将受到影响
• 如果新版本有问题, 回滚也将消耗大量时间, 造成服务长时间不可用
 
适用场合:
• 开发测试环境
• 非关键应用(用户影响面小)
• 初创公司什么都缺,找夜深人静用户访问量小的时间干
 
 
2、蓝绿发布
 
在一般情况下,升级服务器端应用,需要将应用源码或程序包上传到服务器,然后停止掉老版本服务,再启动新版本 (蛮力发布)。
这种简单的发布方式存在两个问题:
• 在新版本升级过程中,服务暂时中断
• 如果新版本有BUG,升级失败,回滚起来也非常麻烦,容易造成更长时间的服务不可用。
 
为了解决这些问题,人们研究出了多种发布策略,其中, 蓝绿发布就是一种
所谓蓝绿发布,是指同时运行两个版本的应用
如图所示,蓝绿部署的时候,并不停止掉老版本,而是直接部署一套新版本,等新版本运行起来后,再将流量切换到新版本上。
 
蓝绿部署原理上很简单,就是通过冗余来解决问题。
通常生产环境需要两组配置(蓝绿配置),一组是active的生产环境的配置(绿配置),一组是inactive的配置(蓝绿配置)。
用户访问的时候,只会让用户访问active的服务器集群。在绿色环境(active)运行当前生产环境中的应用,也就是旧版本应用version1。
当你想要升级到version2 ,在蓝色环境(inactive)中进行操作,即部署新版本应用,并进行测试。
如果测试没问题,就可以把负载均衡器/反向代理/路由指向蓝色环境了。随后需要监测新版本应用,也就是version2 是否有故障和异常。
如果运行良好,就可以删除version1 使用的资源。如果运行出现了问题,可以通过负载均衡器指向快速回滚到绿色环境。
 
优势:
• 操作简单
• 升级切换和回退速度非常快
 
不足:
• 需要两倍机器资源, 成本较高
• 切换是全量的,如果 V2 版本有问题,则对用户体验有直接影响
 
适用场合:
• 对用户体验有一定容忍度的场景
• 机器资源有富余或者可以按需分配
• 暂不具备复杂滚动发布工具研发能力
 
3、灰度发布
灰度发布又叫金丝雀发布.
17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。
空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。
当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测指标,以便在危险状况下紧急撤离。
 
灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。
AB Test 就是一种灰度发布方式:
1. 让大部分用户继续用 A,少部分用户开始用 B
2. 如果用户对 B 没有什么反对意见,那么逐步扩大范围,直到把所有用户都迁移到 B 上面来, 发布完成
3. 如果 B 有问题, 则直接回退到 A , 这样,就会将负面影响控制在最小范围内
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度
 
在新版本应用发布时,为了服务器不停机升级,使用灰度发布策略
在灰度发布开始时,使用HTTP Header 匹配指定测试人员的流量到新版本上,然后当新版本内部测试通过后,可以再按百分比,将用户流量一点一点导入到新版本中,比如先导入10%观察一下运行情况,然后再导入20%,如此累加,直到将流量全部导入到新版本上,最后完成升级,如果期间发现问题,就立即取消升级,将流量切回到老版本。
 
运用灰度发布,就再也不需要加班到深夜进行停机升级了,在白天就可以放心大胆地、安全地发布新版本。
 
灰度发布/金丝雀发布由以下几个步骤组成:
• 准备好部署各个阶段的工具,包括:构建工具,测试脚本,配置文件和部署清单文件。
• 从负载均衡列表中移除掉“金丝雀”服务器。
• 升级“金丝雀”应用(排掉原有流量并进行部署)。
• 对应用进行自动化测试。
• 将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
• 如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。(否则就回滚)
 
 
优势
• 保证整体系统稳定性,在初始灰度的时候就可以发现、调整问题,影响范围可控
• 新功能逐步评估性能,稳定性和健康状况,如果出问题影响范围很小,相对用户体验影响也少
• 用户无感知,平滑过渡
 
不足
• 发布中自动化程度不够,发布期间可能引发服务中断
 
适用场合
• 对新版本功能或性能缺乏足够信心
• 用户体验要求较高的网站业务场景
• 缺乏足够的自动化发布工具研发能力
 
4、滚动发布
滚动发布(Rolling Update Deployment)
在金丝雀发布基础上的进一步优化改进,是一种自动化程度较高的发布方式,用户体验比较平滑。
滚动式发布一般先发 1 台,或者一个小比例,如 2% 服务器,主要做流量验证用,类似金丝雀 (Canary) 测试。
每次发布时,先将老版本 V1 流量从 LB 上摘除,然后清除老版本,发新版本 V2,再将 LB 流量接入新版本。这样可以尽量保证用户体验不受影响。
回退是发布的逆过程,将新版本流量从 LB 上摘除,清除新版本,发老版本,再将 LB 流量接入老版本。和发布过程一样,回退过程一般也比较慢的。
 
一次滚动式发布一般由若干个发布批次组成,每批的数量一般是可以配置的。例如第一批 1 台(金丝雀),第二批 10%,第三批 50%,第四批 100%。
每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次,所以总体上滚动式发布过程是比较缓慢的 (其中金丝雀的时间一般会比后续批次更长,比如金丝雀 10 分钟,后续间隔 5 分钟)。
 
优势
• 用户体验影响小,体验较平滑。
 
不足
• 发布和回退时间比较缓慢。
• 发布工具比较复杂,LB 需要平滑的流量摘除和拉入能力
 
 
蓝绿发布、滚动发布、灰度发布等部署方案对比与总结
在项目迭代的过程中,不可避免需要进行项目上线。上线对应着部署或者重新部署,部署对应着修改,修改则意味着风险。
目前有很多用于部署的技术,有的简单,有的复杂,有的得停机,有的不需要停机即可完成部署。本文将对目前常用的部署方案做一个简单的总结。
蓝绿发布(Blue/Green Deployment)
1. 定义
蓝绿部署是不停老版本,部署新版本然后进行测试。确认OK后将流量切到新版本,然后老版本同时也升级到新版本。
2. 特点
蓝绿部署无需停机,并且风险较小。
3. 部署过程
  • 部署版本 1 的应用(初始的状态)
所有外部请求的流量都打到这个版本上。
  • 部署版本 2 的应用
版本 2 的代码与版本 1 不同(新功能、Bug修复等)。
  • 将流量从版本 1 切换到版本 2。
  • 如版本 2 测试正常,就删除版本 1 正在使用的资源(例如实例),从此正式用版本 2。
4. 小结
从过程不难发现,在部署的过程中,我们的应用始终在线。并且新版本上线的过程中,并没有修改老版本的任何内容,在部署期间,老版本的状态不受影响,这样风险很小。并且只要老版本的资源不被删除,理论上,我们可以在任何时间回滚到老版本。
5. 蓝绿发布的注意事项
当你切换到蓝色环境时,需要妥当处理未完成的业务和新的业务。如果你的数据库后端无法处理,会是一个比较麻烦的问题。
  • 可能会出现需要同时处理微服务架构应用和传统架构应用的情况,如果在蓝绿部署中协调不好这两者,还是有可能会导致服务停止。
  • 需要提前考虑数据库与应用部署同步迁移/回滚的问题。
  • 蓝绿部署需要有基础设施支持。
  • 在非隔离基础架构( VM 、 Docker 等)上执行蓝绿部署,蓝色环境和绿色环境有被摧毁的风险。
6. 优势和不足
  • 优势
升级切换和回退速度非常快。
  • 不足
切换是全量的,如果 V2 版本有问题,则对用户体验有直接影响。
需要两倍机器资源。
7. 适用场合
  • 对用户体验有一定容忍度的场景。
  • 机器资源有富余或者可以按需分配(AWS 云,或自建容器云)。
灰度发布
1. 定义
灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB Test 就是一种灰度发布方式,让一部分用户继续用 A,一部分用户开始用 B,如果用户对 B 没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到 B 上面来。
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
灰度发布结构图
2. A/B Testing
A/B 测试是用来测试应用功能表现的方法,例如可用性、受欢迎程度、可见性等等。 A/B 测试通常用在应用的前端上,不过当然需要后端来支持。
A/B 测试与蓝绿部署的区别在于, A/B 测试目的在于通过科学的实验设计、采样样本代表性、流量分割与小流量测试等方式来获得具有代表性的实验结论,并确信该结论在推广到全部流量可信;蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚。
3. 金丝雀发布
我们平常所说的金丝雀部署也是灰度发布的一种方式,在原有版本可用的情况下,同时部署一个新版本应用作为「金丝雀」服务器来测试新版本的性能和表现,以保障整体系统稳定的情况下,尽早发现、调整问题。
矿井中的金丝雀:17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测指标,以便在危险状况下紧急撤离。
灰度发布/金丝雀发布由以下几个步骤组成:
  • 准备好部署各个阶段的工件,包括:构建工件,测试脚本,配置文件和部署清单文件。
  • 从负载均衡列表中移除掉「金丝雀」服务器。
  • 升级「金丝雀」应用(排掉原有流量并进行部署)。
  • 对应用进行自动化测试。
  • 将「金丝雀」服务器重新添加到负载均衡列表中(连通性和健康检查)。
  • 如果「金丝雀」在线使用测试成功,升级剩余的其他服务器(否则就回滚)。
除此之外灰度发布还可以设置路由权重,动态调整不同的权重来进行新老版本的验证。
4. 优势和不足
  • 优势
用户体验影响小,灰度发布过程出现问题只影响少量用户。
  • 不足
发布自动化程度不够,发布期间可引发服务中断。
 
 
滚动发布(Rolling Update Deployment)
在金丝雀发布基础上的进一步优化改进,是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式。
1. 定义
滚动发布:一般是取出一个或者多个服务器停止服务,执行更新,并重新将其投入使用。周而复始,直到集群中所有的实例都更新成新版本。
2. 特点
这种部署方式相对于蓝绿部署,更加节约资源——它不需要运行两个集群、两倍的实例数。我们可以部分部署,例如每次只取出集群的 20% 进行升级。
3. 部署过程
  • 滚动式发布一般先发 1 台,或者一个小比例,如 2% 服务器,主要做流量验证用,类似金丝雀 (Canary) 测试。
  • 滚动式发布需要比较复杂的发布工具和智能 LB,支持平滑的版本替换和流量拉入拉出。
  • 每次发布时,先将老版本 V1 流量从 LB 上摘除,然后清除老版本,发新版本 V2,再将 LB 流量接入新版本。这样可以尽量保证用户体验不受影响。
  • 一次滚动式发布一般由若干个发布批次组成,每批的数量一般是可以配置的(可以通过发布模板定义)。例如第一批 1 台(金丝雀),第二批 10%,第三批 50%,第四批 100%。每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次,所以总体上滚动式发布过程是比较缓慢的 (其中金丝雀的时间一般会比后续批次更长,比如金丝雀 10 分钟,后续间隔 2 分钟)。
  • 回退是发布的逆过程,将新版本流量从 LB 上摘除,清除新版本,发老版本,再将 LB 流量接入老版本。和发布过程一样,回退过程一般也比较慢的。
4. 优势和不足
  • 优势
用户体验影响小,体验较平滑。
  • 不足
发布和回退时间比较缓慢。
发布工具比较复杂,LB 需要平滑的流量摘除和拉入能力。
其它发布方式
上述都是偏传统的发布方式,能覆盖大部分应用发布场景。针对一些关键新功能的上线发布,或者一些特定的场景,还有一些特殊的发布方式。
 
功能开关发布
利用代码中的功能开关(Feature Flag/Toggle/Switch)来控制发布逻辑,一般不需要复杂的发布工具和智能 LB 配合,是一种相对比较低成本和简单的发布方式。这种方式也是支持现代 DevOps 理念,研发人员可以灵活定制和自助完成的发布方式。功能开关的原理如下图所示:
1. 部署过程
  • 功能开关发布需要一个配置中心或者开关中心这样的服务支持,例如携程的 Apollo 配置中心或者开源的 FF4J,这些都支持开关发布。业界还有专门的功能开关 SaaS 服务,例如 LaunchDarkly。通过配置中心,运维或研发人员可以在运行期动态配置功能开关的值。当然,功能开关发布只是配置中心的一种使用场景,配置中心还能支持其它很多动态配置场景。
  • 功能开关服务一般提供客户端 SDK,方便开发人员集成。在运行期,客户端 SDK 会同步最新的开关值,技术实现有推方式 (push),也有拉方式 (pull),或者推拉结合方式。
  • 新功能(V2 new feature)和老功能(V1 old feature)住在同一套代码中,新功能隐藏在开关后面,如果开关没有打开,则走老代码逻辑,如果开关打开,则走新代码逻辑。技术实现上可以理解为一个简单的 if/else 逻辑。
  • 应用上线后,开关先不打开,然后运维或研发人员通过开关中心打开新功能,经过流量验证新功能没有问题,则发布完成;如果有问题,则随时可以通过开关中心切回老功能逻辑。
2. 优势和不足
  • 优势
升级切换和回退速度非常快。
相对于复杂的发布工具,实施比较简单,成本相对低廉。
研发能够灵活定制发布逻辑,支持 DevOps 自助发布。
  • 不足
切换是全量的,如果 V2 版本有问题,则对用户体验有直接影响。
对代码有侵入,代码逻辑会变复杂,需要定期清理老版本逻辑,维护成本变高。
 
影子测试
对于一些涉及核心业务的遗留系统的升级改造,为了确保万无一失,有一种称为影子测试的大招,采用比较复杂的流量复制、回放和比对技术实现。下面是影子测试的一个样例架构图:
1. 部署过程
影子测试一般适用于遗留系统的等价重构迁移,例如 .net 转 Java,或者 SQLServer 数据库升级为 MySQL 数据库,且外部依赖不能太多,否则需要开发很多 mock,测试部署成本会很高,且比对测试更加复杂和不稳定。
  • 目标实现老的 legacy 服务迁移升级到新的 experimental 服务。
  • 测试开始前,需要在测试环境部署一份 legacy 服务和 experimental 服务,同时将生产数据库复制两份到测试环境。同时需要将生产请求日志收集起来,一般可以通过 kafka 队列收集,然后通过类似 goreplay 这样的工具,消费 kafka 里头的请求日志,复制回放,将请求分发到 legacy 服务和 experimental 服务,收到响应后进行比对,如果所有响应比对成功,则可以认为 legacy 服务和 experimental 服务在功能逻辑上是等价的;如果有响应比对失败,则认为两者在功能逻辑上不等价,需要修复 experimental 并重新进行影子测试,直到全部比对成功。根据系统复杂度和关键性不同,比对测试时间短的可能需要几周,长的可达半年之久。
  • 影子测试因为旁路在独立测试环境中进行,可以对生产流量完全无影响。
2. 优势和不足
  • 优势
对生产用户体验完全无影响。
可以使用生产真实流量进行测试(复制比对)。
  • 不足
搭建复杂度很高,技术门槛高,数据库的导出复制是难点。
外部依赖不能太多,否则测试部署成本很高,且比对测试更加复杂和不稳定。
posted @ 2020-10-20 22:01  梦里花落知多少sl  阅读(278)  评论(0编辑  收藏  举报