构建可回滚的应用及上线checklist实践

一、背景

在互联网分布式应用中,如果上线的新版本有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等工具,比如给指定字段名、类型、是否必填、不填写的默认值等。

3、多版本发布

对于客户端API服务或者基础服务来说,用户升级会有很大的延迟,对于服务提供方来说则需要尽量保证多版本同时可用。最好在最开始设计接口的时候就添加version字段,保证以后的扩展。

4、静态资源发布

因为静态资源一般放在CDN上缓存时间设置的比较长,比如1个月。这样假设发布的版本有问题,需要清理CDN缓存,并且也需要清理浏览器缓存,而且因为存在版本覆盖的问题,即使覆盖了也不一定保证是操作正确了。

现在的工具默认都会把md5设置到js、css文件名中,可有效的避免以上问题。

image-20211120215947571

三、上线checklist

尽管准备工作做的再好,难免也会出现疏漏,因此指定上线前checklist,组内同学交叉评审,保证上线前的最后一步,是很有必要的。

发布策略一般是从下游逐步向上部署。而回滚方案相反,一般是从上游往下回滚。

通用的checklist需要考虑以下几方面:

1、依赖

(1)存储(数据库、分布式缓存)

是否有数据库变更需要代码上线前先提交,并且验证执行成功。

(2)动态配置

首先需要确认代码中的动态配置有无默认值,没有默认值需要先在动态配置系统上添加相关的配置。

(3)下游

确认下游jar包版本是否正确,线上最好使用release包。

确认下游的业务方是否已经上线。

(4)鉴权

美团内部的服务调用都有鉴权,检查鉴权是否已经添加并且已生效

2、上游

(1)Nginx层

确认路由策略,在发布过程中会不会造成用户不断刷新页面命中不同代码逻辑,给用户带来用户体验上的问题和困扰。

(2)上游业务方

确保和上游业务方沟通好,等当前服务全量发布后且观察、验证没问题再通知上游发布。

3、业务内部

通过代码review,QA测试等方式保证上线对现有业务逻辑没有影响。

如有必要可建设业务的checklist规范

  • 代码review:重点查看代码规范、业务逻辑的正确性、对相关功能的影响

  • 测试用例:测试相关代码的正常逻辑、边界条件、其他功能不受影响,如果写好测试用例请参考其他专业的文档

  • 自动化测试:有条件的团队建议添加自动化测试,来保证核心业务流程的正确性

四、可回滚发布

1、回滚方案

需考虑以下几方面:

  • 是否有动态开关、流量控制可以一键恢复到旧版本逻辑

  • 回滚代码会不会导致上游调用失败

  • 回滚代码:根据docker镜像、Git commitId、Git tag回滚

2、可回滚验证

方案设计要考虑可回滚性;通常要在test或预上线环境验证(演练)可回滚性。同时QA同学要把可回滚作为质量验收的一部分。

3、平滑升级

(1)线上验收

通过staging环境或线上灰度链路, 进行线上验收。

(2)蓝绿发布

线上部署两个集群,每个集群都能抗住所有的流量,发布的时候一个集群接受用户请求,等当前集群全部发布成功后,再把流量全部迁移到新版本集群。

优点:可保证新版本特性同一时间对所有用户生效;保证系统高可用,一个集群出问题,可快速切换到备用集群;

缺点:日常使用的机器只有一半,造成浪费;

蓝绿发布的高配方案:部署两套集群,通过Nginx层动态切换集群。

蓝绿发布的低配方案:用动态开关控制新旧逻辑,等新版本全量上线后,再切换到新代码逻辑。

(3)灰度发布(金丝雀发布)

采用金丝雀部署,可以在生产环境的基础设施中小范围的部署新的应用代码。一旦应用新发布,只有少数用户被路由到它。最大限度的降低影响。检测新版本没问题,再逐步扩大发布范围直至全量。

实现灰度发布,需要部署系统设置分批发布,同时必须有监控、报警等相关的系统的配合。确定没问题后再扩量。

还有一点需要注意的就是灰度路由策略,一般服务中用的多是的随机策略,这样可能导致用户在发布过程中不断刷新页面,可能会来回命中新老版本逻辑,影响用户体验。避免方式有以下几种:

  • 采用用户ID做路由因子,问题是新增、删除机器时,算法匹配的机器会变,就需要引入一致性Hash算法,复杂性较高

  • RPC路由策略一般不能执行路由规则,就需要程序自己判断。常用做法是采用动态配置设置百分比值,算法如下:

userId % 100 < $dynamicTrafficPercent ? oldVersion : newVersion
(4)AB测试

AB测试虽然也有流量控制的功能,但一般是用于验证不同版本之间的性能、用户体验、效果数据等的手段。是上线后由运营控制的。

AB测试和灰度发布最大的不同是AB测试是通过桶的方式分配流量。

4、监控报警

常用的发布相关的监控报警包括:

  • 新、旧版本的流量及百分比

  • 对外提供的接口的性能指标、下游的性能指标(TP50、TP90、TP99、TP999)

  • 异常指标及报警

  • 业务指标

5、发布完成周知

  • PM: 周知PM关注业务指标、客诉等

  • 上游:如果上游依赖此发布,周知上游开始发布

  • 下游:周知下周注意流量增量及耗时等情况

五、上线步骤及规范

1、不在高峰期上线,如必须上线,要发邮件申请,同时降低并发度

2、上线前周知

3、保证能回滚

4、发布过程采用分组发布(强制)

5、上线过程中观察系统指标、业务指标、异常指标等;如有异常立即禁用已发布机器

6、上线后周知PM、上下游等

7、有异常第一时间回滚

六、总结

从本文可以看出,保证线上稳定性是一个复杂且系统的工程,需要从技术规范、流程规范、周知、检查、工具支持等各个方面来保证。

作者简介:木小丰,美团Java高级工程师,专注分享软件研发过程中的实践、思考?;队刈⒐埠牛篔ava研发

原文链接:构建可回滚的应用及上线checklist实践

更多精彩文章:

Maven依赖冲突问题排查经验

升级Java17问题记录

使用Groovy构建DSL

Gradle最佳实践

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容