持续交付2.0的快速验证环要求团队能够高频发布,尽快验证最小可行性解决方案;是否高频发布会带来版本质量的下降和生产环境的不稳定?相关统计表明,随着部署频率的提升,以及总代码量和提交量次数的提高,严重缺陷数量并没有随之提高。
收益与成本共存
高频发布模式中,每次发布的内容通常都会少于低频发布中每次发布的内容量,收益主要包括:
- 有更多机会与真实用户互动,从而快速决定或调整自己产品的前进方向;
- 由于每次变更规模较小,软件系统没有剧烈的变化,从而降低部署风险;
- 单次部署成本降低,且趋于恒定,小迭代变更影响范围受控,自动化设施的建设也降低了成本和精力;
- 出现问题易定位、易修复,且能够快速更正。
无论怎样,都无法保证100%消除发布风险,不断寻找降低发布风险的方法是一个重要的问题。
降低发布风险的方法
蓝绿部署
- 准备两套完全一致的运行环境,其中一套环境作为正式环境,对外提供服务;
- 另一套环境作为新版本的预生产环境,部署软件的新版本,并对其进行验收测试;
- 当确保没有问题后,将访问流量引流到这个新版本所在的环境中,作为正式的生产环境,同时保持旧版本所在环境不变;
-
确定新版本没有问题后,再将旧版本所运行的环境作为下一个新版本的预生产环境,部署未来的新版本,“蓝”和“绿”仅代表两个相互独立的部署环境。
在实际应用过程中,数据库的复制的时间成本很高,而且空间成本也很高,因此,很多蓝绿部署方案会使用相同的数据库服务,只是软件部署使用不同的两套环境。这种情况下,要求同一个数据存储格式必须对新旧两个软件版本做兼容性处理。
滚动部署
从服务集群中选择一个或多个服务单元,停止服务后执行版本升级,再重新将其投入使用,循环往复,直至集群中所有服务的事来都更新到新版本。与蓝绿部署相比,这种方式更节省资源。
金丝雀发布与灰度发布
金丝雀发布:通过让一小部分用户先行使用版本,以便提前发现软件存在的问题,从而避免让更多用户收到伤害的发布方式。
金丝雀发布的来源:17世纪英国矿工发现金丝雀对瓦斯气体很敏感,为了保证安全,矿工们每次下井工作时都带上一只金丝雀,如果金丝雀因无法抵抗瓦斯气体而死亡,矿工就知道井下有毒气,立马停止工作回到地面。
灰度发布:将发布阶段分成不同的阶段,每个阶段的用户数量逐级增加,如果新版本在当前阶段没有发现问题,就再扩展用户数量进入下一阶段,直至扩展到全部用户,它是金丝雀发布的一种延伸。
实现金丝雀和灰度发布的两种方式
- 开关隔离方式:将软件的新版本部署到生产环境中的所有节点,通过配置开关的方式,针对不同范围的用户开放新功能,在网络接入层、Web层、业务逻辑层都可以用于设计灰度方案,具体的灰度方案需要根据具体业务场景确定;
- 滚动部署方式:将软件新版本部署到生产环境中的一部分节点上
暗发布
功能或特性在正式发布之前,将其第一个版本部署到生产环境,以便在向最终用户提供该功能之前,团队可以对其进行测试,并发现可能的错误。“暗”,代表用户无感知,可以通过开关技术来实现。例如,某公司重新开发了一个在线新闻推荐算法,就可以配置一个开关,当开关打开时就会有流量流入这个算法,但用户不知道他使用的是新算法或者老算法,如果一旦性能不好或者功能存在问题,则立即关闭这个开关。还可以通过流量克隆的方式来进行,对每次请求都克隆一份,发送给新算法验证。
高频发布支撑技术
某个功能比较复杂,无法在两次发布之间完成开发,如何来处理这个问题?
- 拆分功能:将一个功能进行分解,分解为更小的在一个开发周期内能够完成的功能集;
-
先后再前:先实现服务端功能,再实现用户界面,即先实现用户不可见的功能,同时要确保不影响原有功能,即使新功能的代码被带到生产环境中,因为没有操作入口,也不会对发布有影响,同时可以通过使用暗部署+流量克隆的方式来验证新功能在后头服务端实现方面的质量。
功能开关技术
对高频发布的软件部署来说,开关技术的两种新的用途:
- 隔离:将未完成功能的代码隔离在执行路径之外,使之对用户不产生影响;
- 快速止血:一旦生产环境出了问题,直接找到对应功能的开关选项,使其设置为关闭。
数据迁移技术
- 只增不删:字段尽可能只增不删,对数据库表中的原有字段不再进行修改和删除操作,做到版本兼容,便于平稳升级和快速回退
- 数据迁移:对于无法做到兼容的变更,比如数据库软件变更,原有系统拆分等,为了确保安全,通常按照以下五个步骤:
- 为数据库结构增加一个新版本;
- 修改应用程序,同时向两个版本的结构中写入数据;
- 编写脚本程序,以后台服务的方式将原来的历史数据回填到新版本的结构中;
- 修改应用程序,从新旧两个版本中读取数据,并进行比较,确保一致;
- 当确认无误后,修改应用程序,只向新版本结构写入数据,可将原来的旧版本保留一段时间,以防止未预料的问题出现。
升级替代回滚
在版本发布过程中,总会遇到部署或发布后出现一些问题,需要马上修复,如果没有使用开关技术,尽可能以代码升级的方式替代二进制回滚(将最新版本的代码从代码中剔除,然后再次提交),这种场景得益于持续交付的“小步、独立、频繁”的原则。
影响发布频率的因素
在决定软件的发布频率时,需要综合考虑以下影响因素:
- 增量发布带来的收益和可能性
- 每次发布或部署的操作执行成本有多高
- 出现问题的频率与由这些问题带来的成本有多少
- 维护同一软件的众多不同版本带来的成本
- 高频发布模式对工程师的技能要求
- 支撑这种高频发布所需要的基础工具设施与流程完整性
- 组织对这种高频发布的态度和文化取向
总结
因为部署发布有风险,大家均习惯于推迟风险,但是两次发布之间的间隔越长,累积的代码变更越多,所需质量验证时间就越长;通过降低部署发布的风险,在提高发布频率的同时,也会鼓舞团队士气,更能够尽快运行持续交付的验证环,验证探索环得到的最小可行性解决方案,快速指引团队前进的方向。