一、背景
在互联网分布式应用中,如果上线的新版本有bug又不能回滚止损,带来的后果将是灾难性的。因此做到上线可回滚以及上线前的checklist是保证服务稳定性的基本要求。
在简单的场景里直接回滚到上一版个版本即可,但是如果涉及多个上下游和组件、考虑多版本兼容,就需要有好好设计下如何构建可回滚的代码,充分验证后还需要仔细检查上线checklist,最大程度保证线上服务的稳定性。
二、构建向前兼容的代码
回滚指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为。在回滚之后,程序依然能够正常处理,称为可回滚。
不可回滚原因大多是旧程序不能处理新数据,同时新数据又不能丢弃,代码回滚导致旧业务逻辑出错。
保证向前兼容的手段:
1、数据库变更
新加字段:设置默认值,默认值要保证新旧代码逻辑的语义一致性。比如用户表添加了用户状态,默认值要设置为默认有效。
删除字段:新版本全量发布后,最后迭代2-3个版本后,再删除无用字段,同时要做好数据库备份。
新加唯一约束:首先要确保原有的数据值没有重复的,再添加唯一索引,可使用以下SQL验证:
select field,count(1) from table group by field having count(1) > 1
复杂数据库字段变更:
- 通常做法是:双写读旧 -> 新字段离线验证 -> 旧字段全量拷贝至新字段 -> 双读旧为主diff -> 双读新为主diff -> 写新读新 -> 移除旧字段和逻辑;
- 出问题之后,只回滚程序,不回滚数据。
2、对外提供服务API变动设计
(1)对外提供RPC服务
入参新加字段:设置为可选的,如果没设置值,要有老业务逻辑兼容代码
返回值字段:设置为可选的,如果是新版本肯定有值字段,需要在字段描述文档里做好备注
如果入参和返回值结果差异较大,建议新建一个RPC方法,逐渐把业务方调用迁移到新方法
(2)对外提供HTTP服务
HTTP接口和RPC接口的不同是没有强制的约束,数据交换大多采用Json形式,虽然灵活性强,但是约束力低给管理带来很大的成本。因此HTTP接口文档必须给出类似RPC一样的规范,比如Swagger等工