如何让发布丝般顺滑
Posted 快乐崇拜234
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何让发布丝般顺滑相关的知识,希望对你有一定的参考价值。
欢迎关注本人公众号
文章目录
前言
笔者在过去几年的工作中, 曾负责管理过多个项目,也负责过几百万日活的项目,十几人的研发团队,在工作中也总结了一些项目管理经验,参与制定了一些规范,提升团队的整体效率,保障服务的高可用。接下来笔者会将过去的一些经验进行总结,输出文档。
管理相关的大多是软技能,每个人心中都有一套自己衡量标准;而且不同团队的做事风格,人员水平,组织架构,技术架构等都不同,所以笔者的经验也许并不适用于正在阅读文章的您;如果读者有认为不妥之处,欢迎留言交流。
概述
当团队规模扩大,微服务规模扩大,上下游调用关系渐渐复杂,还可能会与其他部门甚至其他公司有调用关系,此时在新需求需要发布上线时,就可能会涉及到多处代码修改,配置修改,DB修改,上下游服务可能会受到影响。
如果不做一个完整的规范,则肯定会出现各种问答,比如有的配置忘记修改了,各个环境的配置更新有遗漏,上线发布出现问题无法回滚等各种问题。
牢记莫非定律:你担心的事情必将发生
,不要抱有侥幸心理,任何不起眼的问题都可能使过去的努力功亏一篑。
本文将笔者过去对于发布
的一些经验进行总结,文末会给出一个checklist
模板。
本文只讲发布
,对于多需求并行开发
的事情将会在git分支管理一文中介绍。
本文中可能会比较少的讲如何具体的实现某一项策略,比如到底如何实现发布时的兼容性,因为不同的业务场景不同,不同的发布所面临的变更点,影响点也都不同。所以笔者这里只是抛砖引玉,具体的方案还是要根据自己的业务具体设计实施。
环境说明
每个公司的开发部署环境大同小异,但还是会有区别,本文中将各环境分为以下几个:
- 开发环境
可能很多开发同学会在本机进行代码的编写及测试,但是有的公司的部分服务本地无法使用,笔者就遇到过由于部分服务本地不可用只能到公司机房环境调试的情况。这里开发环境用于开发同学自测使用。 - 多套测试环境
测试环境每个公司至少都有一套,但是也会有区别。一些基础架构完善的公司会使用持续集成+容器化
来实现灵活动态的创建测试环境,用完即可销毁,这通常在多人多版本并行开发时非常有效。如果基础设施不怎么完善,可能就需要手动搭建几套测试环境了。 - 预发环境
预发布环境,在真正发布到生产环境之前,开发人员利用真是生产的数据验证一些服务的正确性。除正常情况下开发同学验证服务功能之外,这种情况在于一些第三方公司的服务有交互时也比较常见,有一些第三方服务不提供测试环境,只提供外网可访问的正式环境,只是通过测试账户等措施来实现数据的隔离。 - 生产环境
真正对外提供服务的环境 - 灰度发布环境
灰度发布也叫金丝雀发布。有的企业可能会有单独的灰度发布环境,切部分流量或者部分用户到该环境。有的可能直接用生产环境的部分机器来作为灰度发布。不过最终目的是为了服务发布时的高可用,以及验证一些产品的需求,比如对比不同的营销方案看哪个效果好。 - 沙箱环境
一个稳定的测试环境。当下主流互联网公司都是为服务架构,不同服务之间是网状结构,微服务由不同的小团队(可能是不同团队的)开发维护,沙箱环境就是微服务团队对外(其他调用方)提供的一个稳定的测试联调环境。因为我们的测试环境会一直不断的发布新的代码,所以会经常出现系统不可用,甚至会有比较多的BUG,为了不影响其他依赖该服务的团队,需要提供一套稳定的,不经常发布重启的沙箱环境。通常会在代码发布到生产环境后,将同一套代码发布到沙箱环境。 - 压测环境
压测环境主要用于测试同学做压力测试。
接下来主要介绍发布到生产环境的checklist。
发布前的准备工作
发布之前的准备工作是最重要的,任何事情都是预则立不预则废。
那么发布之前需要准备什么呢?
修改点整理
首先需要列出本次发布的内容,有哪些修改点,功能点,责任人,发布人,代码分支,有变化的依赖包等信息
代码修改影响范围
每一次发布中,代码的变更都是最多的。无论是产品需求、技术需求,还是bug fix大概率都会涉及到代码的变更。这里所说的影响范围包括两个方面,一个是代码修改在系统内部的影响范围,第二个就是在服务之间的影响
。
充分正确的评估影响范围
是非常必要的。如果你改了一点代码之后,是仅仅影响到自己的某一些业务逻辑,那么开发同学自己把控得住的影响面及风险的概率就会很大。如果会影响到上下游的多个服务,那么,这就需要去通知各方同学去一起来监控本次发布。保证整个调用链路都是可以正常运行的。
不仅开发同学需要充分的评估影响范围,产品也需要评估业务上的影响范围,来进行业务相关的验证工作。
上线之前可以列一个表格,记录一下影响点及风险点,如:
变更点 | 影响范围(可以有多个) | 责任人 | 风险点 | 回滚策略 |
---|---|---|---|---|
通知所有的相关人员
上面已经评估出影响范围以后,则需要通知相关人员
:什么服务,即将在什么时间进行发布,发布内容是什么,影响范围是什么。
该通知至少提前半天,复杂的则需要提前更久进行通知,而且在发布前几分钟要在此通知确认。
配置变更
目前主流的互联网公司通常都是服务与配置分离。如此一来,如果发生一些变动,只需要修改配置,既可以实时生效,而无需重新发布或重启应用服务。
配置中心就是来做这件事情的。在发布时经常会有许多配置的增删改等。此时,我们就需要有一份完整的文档来记录各项配置的变更情况,以及各个环境是否已经执行了变更
。
配置的变更同样也需要进行影响面的评估
。
我们还有就是配置中心的修改是需要double check
的,而且配置中心是需要记录操作人的执行记录,历史记录的查看,配置的回滚等功能
,来确保配置不会由于误操作而发生生产事故。
以下是配置变更的checklist:
系统名称 | 配置名称 | 配置原值 | 配置新值 | 影响范围 | 回滚策略 | 环境(一个环境一行记录) | 是否已经执行过变更 |
---|---|---|---|---|---|---|---|
DB变更
数据库的变更也是在所难免的。数据库的变更主要分为DDL表结构变更和数据的变更
。
DDL变更,尤其需要注意表中数据量的大小。如果数据量小,影响还不大;如果数据量大,由于在进行数据库变更的时候,会造成表锁
,故而对业务的影响是非常大的。
在线DDL通常会采用类似于pt-online-schema-change
的工具来实现。该工具的基本原理是
- 表格必须有主键或唯一索引
- 整个过程采用
Copy Table To New Table
的方式,也就是新建一个表,把数据拷贝过去,然后在数据拷贝完成后,会对老表和新表进行rename操作。在此期间老表会添加几个触发器用于将数据拷贝过程中发生的 DML 数据同步到新表。 - 该方案表锁的时间比较少 ,对业务影响范围小。
- 缺点就是实现复杂,而且数据拷贝期间会对磁盘IO造成比较大的影响
这里不过多的对pt-online-schema-change
进行介绍,有兴趣的可以Google。
通常来说,涉及的数据库变更的都会在业务的低峰期执行,比如说晚上夜深人静的时候。
涉及到数据变更的情况,尤其需要考虑回滚
。因为这是有状态的数据存储,不像应用服务是无状态的。
系统名称 | SQL语句 | 回滚SQL语句 | 环境(每个环境一行) | 是否已经执行 |
---|---|---|---|---|
定时任务
定时任务可能有一些需要在发布的过程中临时停止,有一些定时任务耗时比较长,处理的数据比较多,可能也没有中断恢复的功能,则需要临时停止任务。这一步也是经常遗漏的。
所以之前一直强调评估影响范围,就一定要把定时任务评估进去。
定时任务可以使用以下表格进行记录checklist:
系统名称 | 定时任务名称 | 发布前是否需要停止 | 其他需要执行的操作 | 发布后是否恢复 |
---|---|---|---|---|
依赖包版本
所有发布到生产环境的依赖包,都需要发布正式release
版本,一定不可以直接将snapshot版本发布上线。
发布顺序
发布顺序也是很重要的,微服务网状的调用链路,服务之间是有先后顺序的。
在评估影响面时已经将上下游的服务评估进去,这里评估发布顺序就很简单了,通常来说都是下游的服务先发布,上游的服务后发布,前端页面通常要在后端发布完成后再发布。当然也不排除例外。
配置变更的先后顺序也要着重考虑。
兼容性
兼容性也是比较容易忽略的事项之一,它是很多发布失败的根源。
兼容性包括接口兼容,配置兼容,数据兼容
。
比如你修改了一个功能,导致对外接口参数发生了变动,你是否考虑到了在发布过程中外部的请求还是老的参数,你的代码是否兼容老的参数?或者一些有状态的数据的变更,是否发布前后,甚至回滚后,应用程序依然可以正确执行?
要做好兼容性,首先要事先想到会有兼容性的问题,然后有针对性的进行设计。
比如接口,是在同一个接口中兼容还是新写一个接口;
尤其还要注意的是,通常应用都是滚动发布,也就是说发布中的某一时刻,一部分请求走的是新代码,一部分是老代码
,就需要同时保证新老程序都可用。
再特别强调一下缓存的兼容性
,这也是比较容易遗漏的点。在实际发布前后,可能某些数据结构发生变更,存储到缓存的数据也发生了变更,导致发布过程中数据格式不兼容(发布时同一时刻会有两个版本的应用程序再跑)
回滚策略
回滚是发布中的重头戏。任何一次发布都需要制定完备的回滚策略。可能大多数发布回滚策略都很简单,但是也不可以掉以轻心。
如果发布后,生产环境出现了问题,异常告警或者用户投诉,那么开发同学只有非常短的时间来排查定位问题,甚至第一时间回滚
(具体时间看服务系统的级别),这个时间需要在发布之前由leader定好,并且强制实施
,如果超时还未解决问题,则必须回滚,若未回滚,则属于发布人的工作失误。
回滚前需要保留现场,如应用日志,GC日志,服务器CPU,IO等负载情况。
在之前的各项都已经完成的情况下,回滚方案一般也就出来了。
通常来讲,回滚需要制定一个回滚的顺序:配置,DB,代码等回滚的顺序。
代码的回滚:通常大企业中的发布系统都是支持回滚的,回滚到上一次的代码。如果不支持,则需要借助于分支管理,发布上个版本的代码,关于分支管理奖在后续文章写。
其他配置的回滚:回滚时务必将本次所有修改全部回滚,以避免不必要的麻烦。
git代码回滚:如果在发布后,代码已经合并到master分支,此时发生了回滚,则git上master分支的代码也需要回滚。
checklisk 评审
上述全部执行完成后,会输出一个完整的checklist,leader或者本次发布的负责人,需要组织相关人员进行发布评审,不需要花太多时间,主要是为了检查是否有遗漏,各个方案是否完备。
发布时
滚动发布
目前主流的都是滚动发布 ,不会一次性全都发布,否则会造成stop the world 。
滚动发布一般会有两种策略:逐台发布、分组发布
。
具体使用哪个策略也是要具体问题具体分析,如果你的应用服务比较多,如几百台,那么肯定是要分组发布了。但是这里务必需要注意的是每一组服务不要太多
,不要因为发布过程中部分机器重启,导致其他剩余机器压力过高甚至发生宕机,影响用户体验。
在发布时可以先发布一台,观察日志及报警,如果正常再继续发布。
监控
发布过程中要实时监控日志、报警、投诉
等信息。
虽然上面已经做了充足的准备,但是谁也不能保证100%不出问题,所以要提高对自己的要求,谨慎对待每一次发布。
如果发现了异常,则需要紧急定位问题,这是第一优先级的事情。如果在规定时间内没有解决则进入回滚流程。
发布后
验证功能
在顺利发布成功后,则进入验证环节。
验证环节主要针对变更点及影响范围,在线上真实环境进行业务处理,观察执行流程及结果是否与预期相符。
代码合并到master分支,并发布到沙箱环境
这里可以有个延时,在发布多久以后再合并到master分支和发布到沙箱。具体时间要看各个业务具体情况。
其他
- 任何生产环境的变更(包括但不限于代码,配置,数据,Redis等)都要走发布流程,确保任何生产环境的变更都有迹可循
- 禁止留有后门程序
- 禁止搭车发布。不同的需求分开发布,哪怕一天发布多次也不可以搭车合并发布,否则出问题很难快速定位问题,万一回滚影响面会扩大很多。
- 复盘:复盘通常发生于发布失败回滚时。当然发布成功也可以复盘。复盘的主要作用是经验总结,问题分析,避免后续犯同样的错误,保证持续交付能力。
附:完整的checklist
- 发布内容说明
系统 | 发布内容说明 | 责任人 | 影响范围说明 | 影响业务及人员 | 发布人 | 代码分支 | 有变化的依赖包 | 发布顺序 |
---|---|---|---|---|---|---|---|---|
- 上线前准备
配置变更
系统名称 | 配置名称 | 配置原值 | 配置新值 | 影响范围 | 回滚策略 | 环境(一个环境一行记录) | 是否已经执行过变更 |
---|---|---|---|---|---|---|---|
DB变更
系统名称 | SQL语句 | 回滚SQL语句 | 环境(每个环境一行) | 是否已经执行 |
---|---|---|---|---|
定时任务
系统名称 | 定时任务名称 | 发布前是否需要停止 | 其他需要执行的操作 | 发布后是否恢复 |
---|---|---|---|---|
依赖包
记录所有依赖包的变更情况,用于再次检查。
发布顺序
变更内容 | 发布方案说明 | 发布顺序 |
---|---|---|
这里发布方案可能比较少用到,主要是对于复杂的发布流程进行情况说明
回滚方案
变更内容 | 回滚方案说明 | 回滚顺序 |
---|---|---|
以上是关于如何让发布丝般顺滑的主要内容,如果未能解决你的问题,请参考以下文章
Flutter -Listview 4个优化能让你的列表丝般顺滑