前言
最近在进行单元化建设方面的的工作,其中涉及服务分组和蓝绿发布相关的概念,在这里总结一下了解到的相关知识。
版本更新策略
功能开关
在应用逻辑里内置功能开关,通过开关的打开关闭来决定执行新旧逻辑,无需路由机制支持,开发人员可以灵活的控制程序的表现。这种方式需要动态配置中心的支持,目前业界已经有比较完善的解决方案,比如Apollo、spring cloud config等等。具体的方式类似这样:
if Config.SwitchOn {
//new logic
} else {
//old logic
}
功能开关的方式虽然简单直观,但是随着版本的更新需要经常清理过期配置,维护成本比较高。
灰度部署/金丝雀部署
灰度部署是指先更新一小部分服务器比如2%,然后对应用进行测试验证。如果验证通过,则继续更新剩余部分的服务器,否则进行回滚。灰度部署的好处就是影响面小,出现问题时只会影响很小一部分用户,适合对新功能信心不足或是对服务可用性要求比较高的场景。
滚动部署
滚动部署更像是灰度部署的增强版,当新版本经过灰度验证通过之后,我们逐渐增大灰度部署的范围,直到全部的服务器都更行到新版本。在部署过程中需要支持平滑切换,即先把服务器从负载均衡列表中摘除;此外滚动发布通常是分批次的,比如第一批10%,第二批30%,第三批100%等等。
滚动部署相比灰度部署,需要自动化部署工具以及完善的路由机制支持,这样才能保证用户体验足够平滑;此外滚动部署比起灰度部署的发布和回滚时间也会更长。
蓝绿部署
蓝绿部署技术是指同时维护两套相同的生产环境,我们可以称之为蓝色环境和绿色环境,而只有一个颜色的环境负责提供完整的服务,另一个环境则完全空闲。当我们需要部署新版本的服务时,我们先在空闲的环境进行部署和验证,当验证完毕后,通过操作路由将客户端流量切换至新版本的环境,而原先的环境则变为空闲环境,依次循环交替。
要实现蓝绿部署,需要几个额外支持:
- 完善的、操作成本低的路由控制机制,运维人员可以动态地进行流量切换
- 冗余资源,任意时刻其中一个环境的资源是闲置的。当然我们可以把闲置的环境作为预发验证环境,或者把删除一部分空闲环境的资源,等下次发布时再扩充资源
蓝绿部署的好处:
- 可以降低停机时间,我们的生产环境几乎没有停机时间,切换在很短的时间内即可完成
- 可以快速回滚,当新功能不符合预期是我们只需要将流量切换回上一个版本的环境即可
- 可以提高灾备能力,当一个环境出现问题时我们可以迅速切换到另一个可用的环境。实际上每次发布都相当于进行了一次灾备切换
蓝绿部署的不足:
- 资源利用率不足,因为一般的资源是闲置的
- 当流量切换完毕之后,可能在后端仍有业务逻辑没有处理完毕,需要额外的机制保证。你可以在设计时就保证两个环境可以同时处理事务,这样就不需要考虑这个问题了;也可以在切换流量前先将服务设置为“只读模式”,流量切换完毕再回到“读写模式”等等。
- 新旧版本可能会涉及数据库表结构的变化,这时我们需要额外的数据库兼容措施。当切换到新的环境发生问题时,可能会因为新的逻辑导致数据差异。要解决这种问题可以将数据库重构与应用发布分开:先进行数据库重构以保证新旧版本兼容,数据库重构完毕后再进行应用发布。
其他概念
单服务器组合双服务器组
前面提到的蓝绿部署需要两个环境,实际上就相当于双服务器组。二灰度部署和滚动部署也可以用于双服务器组。比如双服务器组中的灰度部署就是在蓝绿环境切换时不是一刀切,而是先切换一小部分到新环境,验证通过后再全量切换到新环境;而滚动部署在双服务器组中就是分批次切换到新环境。
服务器组
在进行服务器组划分时,可以有不同程度的划分:根据数据中心划分,比如A机房为一组、B机房为一组;根据逻辑分组划分,比如A、B机房的一半机器分为一组、剩下的另一半机器分为一组。无论如何分组,请求在服务之间传递时都是需要识别某个机器的分组标识的,比如在注册中心中服务实例的元数据里需要有类似"group=group1"这样的标识,这样客户端或者代理节点在进行路由时才能识别服务端实例所在的分组。
路由机制
前面提到的各种部署策略,实际上都需要不同程度的路由机制支持。对于HTTP服务可以使用代理节点的方式,在域名解析过程中分发到不同的下游节点;RPC服务则需要实现配套的路由机制了。