1 什么是灰度发布,有哪些好处?
介绍:
- 灰度发布是指在黑和白(0和1)之间,能够平滑过渡的一种发布方式。
- 灰度发布,只升级部分服务,即让一部分用户继续用老版本,一部分用户开始用新版本,如果用户对新版本没有不良反馈,那么逐步扩大范围,把所有用户都迁移到新版本上面来,从本质上来说就是用户范围的逐步扩大。
- 灰度发布的本质是逐步生效和风险控制,最终的核心对象是用户,因为所有服务和数据的变更最终都需要面向用户生效。
好处:
- 降低发布影响面: 就算出问题,也只会影响小部分用户,从而可以提前发现新版本中的 bug,然后提前修复,避免影响大部分用户;
- 提升用户体验: 除了能发现 bug,还能很好的收集新版本的用户使用反馈,从而提前调整系统,提升用户体验,也能给后续的产品演进带来参考价值。
- 可以做到不停机的热迁移,版本回滚便捷(速度快)
2 灰度发布几种类型
灰度发布的主要分类:
- 金丝雀发布
- 滚动发布
- 蓝绿发布
2.1 金丝雀部署
金丝雀部署又称灰度部署(或者,灰度发布),是指在黑与白之间,能够平滑过渡的一种发布方式 。
金丝雀部署比较典型的例子,就是我们在使用某个应用的时候,该应用邀请我们进行“内测”或者“新版本体验”,如果我们同意了,那么我们就成了金丝雀。
我们来看一下金丝雀部署的步骤:
- 从负载均衡列表中移除掉一台v1服务器
- 将v2服务器重新添加到负载均衡列表中(连通性和健康检查)
- 如果v2在线使用测试成功,升级剩余的其他服务器(否则就回滚)
优点:用户体验影响小,金丝雀发布过程出现问题只影响少量用户
缺点:当升级全部剩余实例时,如果流量过多,可能会导致服务中断。
2.2 滚动部署
介绍
滚动部署,同样是一种可以保证系统在不间断提供服务的情况下上线的部署方式。和蓝绿部署不同的是,滚动部署对外提供服务的版本并不是非此即彼,而是在更细的粒度下平滑完成版本的升级。
如何做到细粒度平滑升级版本呢?
- 滚动部署只需要一个集群,集群下的不同节点可以独立进行版本升级。比如在一个 12 节点的集群中,我们每次升级 4 个节点,并将升级后的节点重新投入使用,周而复始,直到集群中所有的节点都更新为新版本。
滚动部署的步骤:滚动发布则是在金丝雀发布的基础上进行的改进和优化,第一次也是使用金丝雀发布,后续则使用多批次的形式发布剩余实例,每次批次之间会进行观察,如果有问题,再进行回滚。
优点:
- 1.只需要维护一个集群,成本低
- 2.用户体验影响小,体验较平滑
缺点:
- 1.上线过程中,两个版本同时对外服务,不易定位问题,且容易造成数据错乱;
- 2.升级和回滚以节点为粒度,操作相对复杂。(举个例子,在某一次发布中,我们需要更新 100 个实例,每次更新 10 个实例,每次部署需要 5 分钟。当滚动发布到第 80 个实例时,发现了问题,需要回滚。这时,我们估计就要疯了。)
核心点
在实施滚动发布时,确保新旧版本的平稳过渡至关重要。以下是进行业务设计迭代时需要考虑的关键事项:
- 确保 API 的向前兼容性
在设计新版本的 API 时,需确保其能够兼容旧版本的接口。这意味着新版本应能够处理旧版本的请求和数据格式,以避免服务中断。
-
具体措施:
- 保留旧API接口,允许新旧版本同时运行。
- 引入新的功能时,确保不影响旧功能的使用。
- 数据结构的兼容设计
在数据层面,新版本可能会引入新的字段或数据结构。设计时需考虑如何保证旧版本能够正常处理现有数据。
-
具体措施:
- 使用可选字段或默认值,以避免旧版本因缺少新字段而出错。
- 制定数据迁移策略,确保新旧版本的数据能够顺利过渡。
3. 明确的回滚策略
在设计迭代过程中,考虑到回滚的可能性是必要的。如果新版本出现问题,能够迅速切换回旧版本可以降低风险。
-
具体措施:
- 确保旧版本能够正常处理所有流量,制定清晰的回滚流程。
- 设计数据回退机制,确保数据的一致性和完整性。
- 完整的测试覆盖
在发布新版本之前,进行全面的测试是确保平稳过渡的关键。测试应涵盖新旧版本之间的交互和兼容性。
-
具体措施:
- 进行集成测试,确保新旧版本能够无缝协作。
- 实施性能测试,验证新版本在高负载下的稳定性。
示例:
每个服务在滚动发布过程中都会存在新老版本同时存在的情况,兼容性设计是核心要点。
数据映射关系从一对多修改成一对一:
API方面:API中针对新老版本维护不同的处理逻辑;
数据结构方面:
- 存量数据需要进行拆解成一对一关系,增加新字段在存储,通过老数据的快照保证回滚;
- 新需求通过新字段维护,并对新字段增加默认值;
完整的测试覆盖方面:在测试环境保留一对多的订阅进行兼容测试。
适用场景
适应持续交付流程
- 频繁发布:在持续交付的环境中,滚动发布更适合频繁的小版本更新,而蓝绿部署通常适用于较大的版本发布,可能导致发布频率降低。
适应无状态服务
- 无状态性:对于无状态服务,滚动发布特别适合,因为它可以在不影响用户会话的情况下逐步更新实例。
业务迭代的滚动发布
发布过程可以分成多个子步骤:数据结构变更、模块版本迭代:启动机器、发布服务、接入新服务流量、关闭老服务流量、关闭老服务、关闭老机器,每个节点都能满足可灰度、可回滚。
部署方式的关键在于模块实例的数量通常为个位数,所以基本会每个模块都确认正常才关闭对应老服务,其他主要原因:
- 资源利用:在滚动部署过程中,其他实例可以持续提供服务,从而充分利用系统资源,避免因整个环境迁移而导致的资源浪费。
- 简化操作:滚动部署无需维护两个独立环境,简化了操作和管理流程。
- 适应现有架构:对于传统架构或资源有限的系统,滚动部署能够更好地适应现有的基础设施和工作流。
- 降低成本:由于不需要额外的环境和资源,滚动部署在成本上通常更具优势,特别是在小型项目或预算有限的情况下。
设计阶段
- 方案设计评审阶段保证API、数据结构的前后兼容
- 指定明确的回滚策略
测试阶段
- 数据结构层面:验证新旧版本能够正确处理所有业务;
- API层面:验证API改动能够兼容,不会影响外部依赖。
发布过程
模块部署
目前示例的模块线上是两台机器部署,每一个节点不正常都可回退:
- 先发布一台新版本营销服务 V2.0.56.1,检测服务正常启动;
- 接入流量,观察服务日志等是否正常;
- 再发布另一台新版本营销服务 V2.0.56.1,检测服务正常启动;
- 接入流量,观察服务日志等是否正常;
- 关闭老服务流量,关闭两台老版本营销服务 V2.0.55.1服务与机器。
优化方向
- 目前新版本发布后,网关到业务服务处于直连状态,无法对新版本做到精细化流量控制,后续可以增加流量比例分配的分发方式;
- 回退是否能做到一定时间记住关闭的老版本,直接自动化重启;
2.3 蓝绿部署
介绍
蓝绿部署,是一种可以保证系统在不间断提供服务的情况下上线的部署方式。
如何保证系统不间断提供服务呢?那就是同时部署两个集群,但仅对外提供一个集群的服务,当需要升级时,切换集群进行升级。蓝绿部署无需停机,并且风险较小。其大致步骤为:
- 部署集群 1 的应用(初始状态),将所有外部请求的流量都打到这个集群上
- 部署集群 2 的应用,集群 2 的代码与集群 1 不同,如新功能或者 Bug 修复等
- 将流量从集群 1 切换到集群 2
- 如集群 2 测试正常,就删除集群 1 正在使用的资源,使用集群 2 对外提供服务
优点:
- 1.同一时间对外服务的只有一个版本,容易定位问题;
- 2.升级和回滚以集群为粒度,操作相对简单;
缺点:
- 1.需要维护两个集群,成本高;
- 2.切换是全量的,如果 V2 版本有问题,则对用户体验有直接影响;
核心点
在实施蓝绿发布时,进行业务设计迭代时需要考虑的关键事项及相应措施包括以下几个方面:
- 环境准备
确保新旧环境的配置一致,以避免因环境差异导致的问题。
-
措施:
- 确保蓝环境(旧版本)和绿环境(新版本)在硬件、软件和网络配置上保持一致。
- 在新环境中进行全面的验证和测试,确保其与旧环境相同。
- 流量切换策略
设计流量切换方案,以确保在切换期间服务的稳定性。
-
措施:
- 使用负载均衡器进行流量控制,可以逐步增加新版本的流量,减少风险。
- 在切换前进行充分的性能测试,确保新版本能够承载预期的流量。
- 快速回滚机制
确保在新版本出现问题时能够快速切换回旧版本。
-
措施:
- 制定明确的回滚流程,确保能够迅速恢复到旧版本。
- 在切换前做好备份,以便在需要时快速恢复数据和配置。
适用场景
- 对停机时间零容忍:适用于那些不能容忍任何停机时间的业务场景。
- 需要快速回滚:当新版本部署后发现严重问题时,需要能够立即回滚到旧版本的场景。
Nacos升级的蓝绿部署
重新起一套新的云服务:
- 所有业务模块都启动一套(相同实例和数量)
- 复用中间件,除了网关和nacos
- 流量逐步切换到新的云服务
最后一步的流量逐步切换,就是细化的单个服务蓝绿部署操作,通过流量切换来进行nacos新功能验证;
由于nacos与服务挂钩,所以蓝环境不进行中间件部署,来保证数据的一致性,不需要考虑回退引起的数据丢失问题。
考虑点
- 防止节点服务注册数据脑裂:Nacos在集群升级过程中,因为节点之间会进行数据同步,当版本差异情况下不能保证数据完全同步;A,B节点的hash算法不同,在接到请求进行hash计算,如果A节点认为这个请求是B节点处理,转发到B节点之后,B节点也计算了hash,发现不是自己节点处理,导致请求找不到处理节点;
- 保证nacos与服务连接稳定:在新环境可以先确保nacos与服务的正常通信,再进行流量的处理,避免在原环境直接升级,nacos与服务出现不可用,影响范围过大;
- 内部API兼容:内部dubbo针对nacos API进行进一步包装,需要确保版本兼容。
发布过程
- 启动nacos
- 启动网关及业务模块实例
- 灰度切换流量
- 稳定后剔除绿色环境设备
2.4 总结
| 方式 | 零停机 | 生产流量测试 | 针对特定用户 | 机器资源成本 | 回滚时长 | 负面影响 | 实现复杂度 |
|---|---|---|---|---|---|---|---|
| 全量发布 | ❌ | ❌ | ❌ | 低 | 慢 | 高 | 低 |
| 蓝绿发布 | ✅ | ❌ | ❌ | 高(双倍) | 快 | 中 | 中 |
| 滚动发布 | ✅ | ✅ | ✅ | 中(按需) | 慢 | 低 | 高 |
| 金丝雀发布 | ✅ | ✅ | ✅ | 中(按需) | 快 | 低 | 中 |
- 全量发布:只有实现复杂度比价低,没有其他优势
- 滚动发布:发布和回退时间比较缓慢,用户体验比较平滑
- 蓝绿发布:适合于对于资源预算比较充足的业务,或者是比较简单的单体应用,可以快速实现系统的整体变更
- 金丝雀:适合需要针对特定用户或者人群进行现网请求验证的业务,可以显著减低风险