如何保证业务变更的可回滚性

简介: 采用快速迭代的开发方式的互联网公司常常一天之内要对线上业务做多次变更。保证每次变更都可回滚,对于风险控制和开发人员的安全感保障有重要意义。本文介绍了几种保证业务变更可回滚的方法。

背景

采用快速迭代的开发方式的互联网公司常常一天之内要对线上业务做多次变更,如果在变更业务后出现了伤害用户体验或影响收入的意外情况,最简单快速的解决方法就是将线上业务回滚到变更前的状态。保证业务变更的可回滚性,对于控制风险和保障开发人员的安全感,都有重要的意义。本文介绍了几种保证业务变更可回滚的方法。

将代码和配置整体打包

如果将代码和配置分开部署,在回滚的时候就会遇到"应该是先回滚代码还是回滚配置"的难题,所以,要想轻松回滚,在部署的时候,一定要将代码和配置整体打包。在具体的实践方式上,我强烈建议采用容器化部署,在CI系统中将变更后的代码和配置build为一个docker image, 并给不同版本的容器打上不同的tag, 通过切换tag便能实现整体服务的快速回滚。

引入中间版本

对于单体应用,采用容器化的手段将代码和配置整体打包部署就能很好的保证可回滚性,但是,这仅是一个过度简化的模型,实际的线上系统则要复杂许多,一般都是由有依赖关系的多个子服务构成。例如,前端web系统会访问后端数据服务,后端数据服务会访问数据库,或者给批量作业系统下发任务。对于这种有依赖关系的变更,怎样开发和部署才能如何保证可回滚性?

首先,系统设计要保证调用的单向性,即如果服务A调用了服务B,那么服务B一定不会调用服务A。在满足单向调用的前提下,可以使用下列方法来保证可回滚性。

例如,有两个子服务A和B,服务A会调用服务B,业务需求需要同时将A变更为A'和将B变更为B'才能实现。

初始状态: A -> B

最终状态: A' -> B'

但是,由于A'和B以及A和B'的实现不兼容,所以不能出现A -> B'或A' -> B的中间状态。

解决办法:

  1. 将B变更为B'',B''可以同时兼容A和A',即A -> B''与A' -> B''均成立, 此时系统状态变为A -> B'',如果发现问题,可回滚成状态A -> B
  2. 将A变更为A', 此时系统状态变为A' -> B'',如果发现问题,可回滚成状态A -> B''
  3. 将B''变更为B', 此时系统状态变为A' -> B', 顺利抵达最终状态,并且切换过程平滑, 如果发现问题,可回滚成状态A' -> B''

综上可见,通过引入中间版本B'',就能保证对存在依赖关系的两个子服务的变更的可回滚性。

举个具体的例子,当前的用户登录系统只要求输入用户名和密码,由前端系统将用户名和密码发送给后端系统进行验证,现在,需要在用户登录时输入验证码。显然,这一改进需要前后端系统一起配合才能实现:

  • 前端系统的界面要加入验证码的图片显示和输入框,并且调用验证接口时需加入验证码参数
  • 后端系统的验证接口需提供对验证码参数的支持

应用前面的解决办法可以得出下面的开发和部署步骤:

  1. 修改后端系统的验证接口,加入对验证码参数的支持,但为了兼容不带验证码的前端系统(版本A),验证码参数是 可选
  2. 上线修改后的后端系统(版本B''),观察是否与A兼容,如果有问题,回滚到版本B
  3. 修改前端系统,显示验证码图片和表单字段,在调用验证接口时传入验证码参数
  4. 上线修改后的前端系统(版本A'),观察该版本是否工作正常,如果有问题,回滚到版本A
  5. 在前端A'和后端B''工作正常后,再修改后端系统的验证接口,将验证码参数由可选改为 必需
  6. 上线修改后的后端系统(版本B'),如果工作正常,业务变更完成;如果有问题,回滚到版本B''

数据迁移的处理

在业务变更涉及数据迁移时,应对数据表的字段采取"只增不删"的原则。原因很简单,当某个字段被当前代码引用的字段被删除后,线上业务是会出问题的,但新增一个没有被当前代码引用到的字段,则不会有问题。

等到确认新版代码工作完全正常,不会再回滚到旧版本时,才将旧字段删除。一旦旧字段被删除,引用到旧字段的旧版本代码就无法工作,也就无法回滚到旧版本了。

总结

  • 使用容器化部署,代码和配置可以整体回滚
  • 通过引入中间版本,让有依赖关系的系统可以分开独立回滚
  • 数据迁移时,不能删除字段,要等到确认新版代码工作正常,无需回滚到旧版时才能删除
目录
相关文章
|
7月前
|
存储 数据库 数据中心
双活中心业务一致性
双活中心业务一致性
81 2
|
3月前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
2月前
|
架构师 Java 数据中心
二阶段提交:确保分布式系统中数据一致性的关键协议
【10月更文挑战第16天】在分布式系统中,数据一致性的维护是一个至关重要的挑战。为了应对这一挑战,二阶段提交(Two-Phase Commit,简称2PC)协议应运而生。作为一种经典的分布式事务协议,2PC旨在确保在分布式系统中的所有节点在进行事务提交时保持一致性。
44 0
|
5月前
|
消息中间件
分布式篇问题之通过本地消息表实现分布式事务的最终一致性问题如何解决
分布式篇问题之通过本地消息表实现分布式事务的最终一致性问题如何解决
224 0
|
7月前
|
算法 安全 程序员
揭秘分布式系统:日志复制如何保障数据一致性?
本文介绍了分布式系统中的日志复制技术,这是保证高可用性和数据一致性的重要手段。以Raft算法为例,文章阐述了Leader如何将客户端请求复制到Follower的日志中:Leader首先记录请求,然后通过RPC发送给Follower,等待ACK确认,必要时进行重试。当多数Follower确认后,Leader提交日志并通知Follower。文中还提到了网络分区和日志一致性等挑战,以及应对策略,如超时机制、领导选举、日志匹配和压缩。最后,强调了日志复制在面对故障时确保系统一致性和可用性的作用。
286 4
|
7月前
|
负载均衡 数据库 数据中心
双活中心事务一致性
双活中心事务一致性
61 2
|
7月前
|
监控 NoSQL Redis
RedisShake如何处理数据同步过程中的冲突和一致性问题
RedisShake保障数据同步一致性,支持全量和增量同步,处理并发冲突(利用乐观锁机制),并进行数据校验。遇到故障能自动恢复和重试,保证不间断同步。同时,提供监控和日志功能,便于识别和解决问题,确保数据完整性。
242 0
|
消息中间件 缓存 Java
虾皮一面:如何保证数据双写一致?
虾皮一面:如何保证数据双写一致?
90 1
《云上业务稳定性保障实践白皮书》——四. 变更管控体系——4.2 变更管控动作——4.2.4 回滚
《云上业务稳定性保障实践白皮书》——四. 变更管控体系——4.2 变更管控动作——4.2.4 回滚
204 0
|
消息中间件 缓存 网络协议
如何通过事务消息保障抢购业务的分布式一致性?
作者:山猎,阿里云解决方案架构师
210 0
如何通过事务消息保障抢购业务的分布式一致性?

热门文章

最新文章