# CI&CD:持续集成、持续交付、持续部署

今天的主题是持续集成、持续交付、持续部署,相信大家都有打包、部署的经历,通过了解CI & CD后,大家会对持续集成、持续交付、持续部署有更加深入的认识。

为了让大家对CI & CD有更深入的了解,首先从传统的部署方式讲起。

# 1、传统部署

# (1)、手动部署

早期部署的时候大多采用手动部署,手动部署的过程也很简单。

首先在本地开发完成以后,执行npm run build命令将代码进行打包,然后将打包后的文件上传到服务器上。

如果是静态文件,直接可以通过url的方式就可以访问了。如果提供服务的话,需要手动执行命令启动服务,然后就可以提供服务给调用方使用了。

手动部署的方式比较简单,但也存在一些问题,比如自动化程度低、不易维护、没有区分环境,容易误操作、上线出问题不能及时处理、无法实现持续部署等。

由于手工部署存在这些问题,逐渐被弃用,同时采用自动化部署的方式来部署上线。

# (2)、自动化部署

自动化部署的方式是将手动部署执行的操作通过脚本的方式来实现,如图所示,将部署脚本的每个命令写入到脚本中,然后通过执行脚本的方式实现部署。

这种部署方式相较于手动部署实现了自动化,而且能够根据环境来部署,可以减少出错概率,同时也便于维护,当部署过程发生变化,只需要修改下脚本就可以了。

自动化部署的方式提升了部署的效率,降低了出错率,但也存在也一些缺点。比如不够灵活,每个项目都需要写一套脚本,脚本的定制化较强。上线出问题不能及时处理,比如回滚,不能应对大规模集群上线等等。

随着 DevOps 的崛起,集成、部署的工作逐步向着工程化的方向迈进。

# 2、DevOps

缩写

DevOps = Development + Operations

DevOps是一组过程、方法与系统的统称,用于促进开发、技术运维和质量保障(QA)之间的沟通、协作与整合。

在软件开发的流程中,为了按时交付,开发、测试、运维需要紧密合作。这些合作和沟通的工具、方法就是 DevOps 。

从图中我们可以看出,DevOps是开发、测试、运维的交集,它涉及各方的协作。

对于大型团队而言,应用程序发布是一项涉及多团队,而且是具有高风险的活动,所以需要强大的部署自动化手段确保部署任务的稳定性,并且减少部署出错的可能性。

一个完善的devops应具备持续集成、持续交付、持续部署的能力。

# 3、持续集成、持续部署、持续交付

CI和CD有3个过程,先从整体上对CI、CD有一个认识,然后再对每个过程详细的讲解。

持续集成:一般包括编码、构建、集成、测试等环节,持续集成的结果是输出可部署的文件。

持续交付:持续交付是建立在持续集成的基础上的,他主要是将可部署的文件部署到测试环境和预发环境来验证业务逻辑的正确性和类生产(预发)环境下代码是否能正常运行。

持续部署:持续部署是建立在持续交付的基础上的,当测试人员验证无误后,将代码部署的线上的过程。

持续,就是说每完成一个完整的部分,就向下个环节交付,发现问题可以马上调整。是的问题不会放大到其他部分和后面的环节。 持续的含义:频繁发布、自动化流程、可重复、快速迭代

# (1)、持续集成CI —— Continuous Integration

集成:通过自动化的构建(包括编译、打包、测试)来部署代码,以尽快发现集成错误。

持续集成:频繁将代码集成到主干和测试环境中,不断发现问题,并对集成结果进行修正。

持续集成强调可重复性,一旦发现问题,这个过程都会在运行一遍,直到当前环节无误为止。

持续集成的核心是编译输出打包后的文件,这和前面传统部署的流程是一致的,只不过这里用了持续集成工具,将集成工具化、平台化,而且屏蔽了项目之间的差异。

一些比较完备的团队在持续集成的过程中会加上单元测试,做一些初步的验证,以尽早发现问题,减少错误向下一环节传递。

持续集成优点:

1、构建自动化:自动化部署工作可以解放集成、测试、部署等重复性劳动

2、尽快地发现集成错误,减少集成引起的问题,加快团队合作的开发速度

3、便于维护,增强软件的可靠性,减低成本:管理流程固化,减少上线问题,问题可控(快速回滚)

4、集成日志及历史记录

5、使用统一的依赖包管理库

# Jenkins —— 一款强大的打包工具

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

Jenkins有很多优点,能提供可以对不同语言的代码进行打包,安装简单,支持在各个系统下安装Jenkins。Jenkins另一大优点是配置的可视化,用户设置都可以在界面上去配置,而且Jenkins的插件众多,众多的插件支持使得Jenkins支持各种场景下的集成任务。

Jenkins

Jenkins的配置主要分为6大类,分别是General(基本配置)、源码管理、构建触发器、构建环境、构建、构建后操作。

General:主要是用于基本配置,比如Jenkins任务名称、描述等等

源码管理:源码管理用于告诉Jenkins在打包前去哪里pull代码,一般支持的代码管理工具有Git、SVN、CVS等,而且也支持同时拉多个项目的代码,配置Multiple SCMs,设置多个仓库的地址和凭证即可

构建触发器:构建触发器是告诉Jenkins什么时候启动执行构建任务,常见的触发方式有通过url的方式触发、通过gitlab的webhook触发、定时触发等等

构建环境:主要是对环境一些处理,比如注入环境变量、密码,构建之前的删除旧的工作空间等

构建:构建用于对源代码做怎样的处理,可以根据项目需要新增不同的构建步骤,一般都会用到执行shell脚本的步骤

构建后操作:构建完成后需要执行的操作,常见的操作有归档、删除工作空间、通知构建成功等

# (2)、持续交付CD —— Continuous Delivery

持续交付:将集成后的代码部署到更贴近真实运行环境的「类生产环境」,如果代码没有问题,可以继续手动部署到生产环境中。

目的:尽快发现生产环境的问题,确保新增的代码在生产环境中是可用的。

划重点

持续交付的侧重点在于交付,其核心对象不在于代码,而在于可交付的产物

持续交付添加了 Test -> Staging -> Production 的流程,Test 环节不仅仅包含基本的单元测试,还需要延伸到更为复杂的功能测试以及集成测试等,Staging 指的是类生产环境(预发环境) ,其尽可能的对真实的网络拓扑、数据库数据以及硬件设备等资源进行模拟,从而为测试人员反馈代码在生成环境中的可能表现。

流程中每一个环节的执行结果都会对开发人员进行反馈,每一个出现的错误都会导致整个流程的再次循环。

当测试完毕确认无误之后,将由相关人员对其进行手动部署到生产环境,验证新代码在生产环境的表现。

# (3)、持续部署CD —— Continuous Deployment

持续部署:在部署的基础上,实现生产环境的过程自动化。

关键点

持续部署强调了通过 automated deployment 的手段,对新的软件功能进行集成。

持续交付 相比 持续集成 的区别体现在对 Production 的自动化,从开发人员提交代码到编译、测试、部署的全流程不需要人工的干预,完全通过自动化的方式执行。

这一策略加快了代码提交到功能上线的速度,保证新的功能能够第一时间部署到生产环境并被使用。

# 4、部署扩展知识

# (1)、部署场景

a、单系统部署

前后端不分离:前端打包成静态文件后,copy 到后端项目中,然后部署后端项目

部署简单,适合流量不大的业务

b、前后端分离部署

前端使用 Nginx 部署,后端运行jar包

适合流量大的业务

存在问题:

1、部署顺序问题,向后兼容的问题

2、不同站点考虑跨域问题

3、对系统稳定性要求高,各系统必须同时提供服务

c、微服务部署

分而治之的部署方式。有效的拆分应用,实现敏捷开发和部署。

各个服务启动后去服务注册中心注册,当有外部调用时,先从注册中心获取服务访问列表和地址,然后又微服务的路由规则来选择访问哪个服务。

# (2)、部署方式:全量部署、增量部署

全量部署是主流部署方式,将原先的服务停掉或者直接采用新服务代替原有服务,这种方式比较常见,大多数业务也是采用这种部署方式。

增量部署:提取当前版本和即将部署版本之间的增量(包括代码、可执行文件或者配置等),并在部署过程中仅更新增量部分。通过新旧版本的比对,提取改变部分,生成增量包。增量部署的优点是部署速度快,节省带宽,缺点是不可预估,回滚麻烦

# (3)、发布方式

a、蓝绿发布

蓝绿发布过程是两套环境交替升级,旧版本保留一定时间便于回滚。

特点:蓝绿部署无需停机,并且风险较小,发布策略简单;用户无感知,平滑过渡;升级/回滚速度快。缺点是需要两倍机器资源。

蓝绿发布适合自动化能力储备不够的团队

b、灰度发布

灰度发布:根据比例将老版本升级,灰度发布能够平滑过渡的一种发布方式。

一部分用户继续用 A,一部分用户开始用 B,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

部署过程

1、从LB摘掉灰度服务器,升级成功后再加入LB;

2、少量用户流量到新版本;

3、如果灰度服务器测试成功,升级剩余服务器;

他的特点是保证整体系统稳定性,在初始灰度的时候就可以发现、调整问题,影响范围可控;用户无感知,平滑过渡。

适合基础服务的更新和重大变化的升级

c、滚动发布

滚动发布:按批次停止老版本实例,启动新版本实例。

红色:正在更新的实例,蓝色:更新完成并加入集群的实例,绿色:正在运行的实例

滚动式发布一般先发 1 台,或者一个小比例,如 2% 服务器,主要做验证用。滚动式发布需要比较复杂的发布工具和智能 LB,支持平滑的版本替换和流量拉入拉出。

特点:用户无感知,平滑过渡;节约资源能及时发现问题;比较适合大流量场景

缺点:部署时间慢,持续的时间比较长,发布策略较复杂;自动化要求高

d、开关发布

通过配置中心,运维或研发人员可以在运行期动态配置功能开关的值

利用代码中的功能开关来控制发布逻辑,是一种相对比较低成本和简单的发布方式。

功能开关服务一般需要提供SDK,方便开发人员集成。

优势:升级切换和回退速度非常快,成本相对低廉

缺点:需要底层提供技术支持,对代码有侵入,代码逻辑会变复杂,维护成本变高

# 5、总结

# (1)、持续集成

将代码打包、检查以符合生产环境的要求。代码提交、编译、测试等一系列环节均可以通过自动化工具完成,很好的节约了人力资源。

# (2)、持续交付

在手动执行的部署环节,还可以添加在执行完毕标准测试之外的需求,以保证发布功能的可靠。 :::

# (3)、持续部署

面向稳定的发布上线后的功能更新。自动的,无需人工干预的部署可以保证新增功能第一时间被发布到生产环境中,确保其尽快的被用户所使用。