服务升级总结提炼
服务升级是所有系统都需要面对的问题,很多问题都是在升级过程中才会出现,基于我目前的经验总结出如下服务升级协议
服务升级应具备的能力
1. 代码向下兼容能力
a. 业务代码向下兼容
业务代码需要根据具体的业务来进行,升级过程中尽量向下兼容几个版本的业务
b. 接口向下兼容
接口兼容是升级很重要的一项能力,因为升级过程中可能涉及到接口改动,建议如下
- 能新增的就别修改
- 如果非要修改,则需要兼容改动之前的接口,新增的请求参数改为非必填,如果是必填项,请在业务代码中校验该参数,校验不通过及时抛错
- 若存在参数不使用,尽可能不要删除该参数,将其改为非必填项即可
c. SDK向下兼容
SDK向下兼容能力必不可少,你永远不知道 SDK 使用方正在使用的 API 有多古老,建议如下
- 对于需要删除的方法,需要提前标记好未来可能会被废弃,先兼容几个版本后再删除
- 使用新增代替修改,请不要修改方法,应当使用新增来替换该方法,到最后再废弃
2. 服务优雅退出能力
服务生命周期会经历三个阶段,分别是启动、运行、退出,大部分时候我们只关注了启动和运行,并没有考虑到服务退出,但很多问题都是由退出不优雅导致的,比如使用 kill -9 pid
强制干掉进程,导致很多正在运行的业务直接中断,最后发生一些难以排查的问题。退出前应该做好数据归档,关闭所有的连接,除非特殊情况,否则不要强制杀死进程
3. 自动升级能力
自动升级可以减少很多由于人员的不熟悉导致的问题,自动升级是升级标准化的体现,可使用持续部署工具进行自动升级
4. 平滑升级能力
服务应该具备平滑升级的能力,升级前后对用户都不应该产生影响。如果不具备平滑升级能力,升级前应该提前通知好各个依赖方,避免应为当前服务升级导致其他服务不可用,如果升级会影响到客户,应当与用户协商好升级窗口,如果超过了升级窗口,应该立刻回滚,与用户协商过程中还需要说明本次升级影响范围等信息,升级应该尽量选择对客户影响最小的时间段发布。
5. 升级失败回滚能力
如果升级失败了或者超过了升级窗口,应当立刻回滚,避免影响客情。请在升级前准备好回滚所有需要的脚本、包等信息,避免由于准备不当影响用户使用。
升级标准化
升级前
-
发布升级公告,通过各种渠道将升级通知触达客户,升级公告中应当包含本次升级的时间窗口、升级内容、影响范围等信息
-
做好备份,提前做好代码(分支)备份、包备份、数据备份,发布最好单独使用一个单独分支,与主干分支区分开,等发布完成了再将发布分支合并到主干分支,并打好 Tag
- 做好升级准备,提前编译打包,对于依赖包升级,请提前 deploy ,如果是容器化交付,则提交打包好镜像。提前准备好升级脚本,升级脚本包含但不限于 Shell 脚本、Python 脚本、SQL 脚本,请注意,SQL 脚本中对数据修改请在事务内,并在事务内验证数据是否正确,如果不正确了直接 ROLLBACK,中断本次发布
- 提供发布文档,发布文档中应当包含但不限于上诉内容
- 基于上诉的发布文档进行发布评审,应当让相关人员知道本次发布的所有内容,减少发布风险,增加发布风险应援
- 发布审批,在发布前应该做好发布审批工作
升级中
- 验证系统是否启动
- 验证系统是否正常,是否存在异常信息
- 验证系统各项基本指标是否正常
- 验证系统各项功能是否正常
- 验证数据是否正常
- 验证本次升级的功能是否正常
升级后
- 持续观察系统是否正常运行,是否存在异常信息,必要时安排人员人肉观察,相关人员应该保持通讯畅通
- 持续观察系统各项指标是否异常,比如系统内存是否正常、核心线程数是否正常等
- 代码合并,及时将代码合并到主干分支,保证主干分支与生产环境代码一致