DevOps之持续集成

简介: 软件持续集成

什么是持续集成?

先说一下什么是“持续”,持续的意思并不是“始终,一直”,它的意思是“随时”。比较恰当的频率是:每当有人提交代码,同时集成一次。


“持续集成”实践最早来自 1996 年 Kent Beck(肯特·贝克)提出的极限编程方法(XP)。他在《解析极限编程——拥抱变化》一书中给出了一个简短的说明:“持续集成是每天多次集成和生成系统,每次都完成一个构建任务”。


在 2006 年 5 月 1 日,Martin Fowler(马丁·福勒)在其个人官网给出了相对正式的定义:

“持续集成是一种软件开发实践,团队成员频繁地将他们的工作成果集成在一起。通常是每人每天至少提交一次,这样每天就有多次集成。每次提交后,自动触发一次包含自动化测试的构建任务,以便能尽早发现集成问题。”


通过这种方式,许多团队大大减少了集成阶段的问题。由此可以看出,持续集成是一种质量反馈的机制,能够尽早地发现代码中的问题,并提前解决问题。


为什么要做持续集成?

作为软件从业人员,我们都知道,软件开发有一个特点,就是在没有开发完成之前,很长一段时间内是无法运行应用程序的。一般都是前期大家开发各自的功能模块,最后在集成阶段将功能集成在一起,进行验收测试。这样做就会导致几个问题:

  • 由于长期在各自的分支上开发,导致在集成阶段合并分支时产生大量冲突,无法合并;
  • 由于之前并未进行过任何集成,导致在集成阶段耗时太长,或者根本无法集成;
  • 由于之前并未进行过任何测试,导致系统集成后发现并不满足要求。


解决上面问题的最佳方法就是持续集成。

目前在谈到集成时,主要有以下两种集成方式。


即时集成:是指团队成员每次提交之后就进行集成,并执行编译、构建、自动化测试等任务来检查个人提交的代码是否可用。这种集成方式要求执行的时间要短,要快速反馈结果,因此只能执行一些简单地测试。

  • 定时集成:类似每日构建(Daily Build),是指每天定时(一般为晚上)自动执行一次集成过程,第二天将执行结果发送给关系人。这种集成方式注重的是检测的全面性和彻底性,对执行时长要求不高。
  • 持续集成一般是指即时集成,但定时集成在某些场景下也是非常有用的。比如,比较耗时的集成过程。


持续集成的工作流程

持续集成服务器可以采用目前最受欢迎的 Jenkins,如下图所示:

image.png


每次提交后具体的执行步骤是:


  • 开发人员在本地工作空间提交代码到代码仓库;
  • 版本控制系统通过 WebHook 等机制实时通知持续集成服务器;
  • 持续集成服务器克隆最新的代码和构建脚本到服务器本地,或者专用的服务器;
  • 在持续集成服务器或专用服务器上执行构建脚本,对最新的代码进行检查,包括编译构建、代码动静态扫描、单元测试以及部署到测试环境运行功能测试等;
  • 运行结束后,自动生成执行结果报告
  • 将执行结果通过邮件等方式通知给开发人员。


为了保证每次集成的效率,以上步骤都是通过自动化方式执行的。开发人员只需要专注于代码开发,提交后只需等待几分钟就能够收到执行结果。这里需要强调的是,虽然开发人员不需要关注除代码开发之外的事情,但对每次提交有要求,比如:要保证每次提交的是一个完整的功能项。代码只写了一半就提交,功能测试肯定是通不过的。


如何实现持续集成

实现持续集成需要一定的先决条件,也就是上图中的几个组成部分,包含版本控制系统、持续集成系统和自动化测试。


版本控制系统

版本控制系统用于存储和软件相关的所有内容,比如应用程序的源代码、数据库脚本、构建脚本和部署脚本等。目前采用的都是基于 Git 的分布式版本控制系统,如GitLab、GitHub、Gitea等。不管是自研的还是开源的,对于应用持续集成实践,版本控制系统提供了基本的版本控制能力,能够记录哪个版本的代码是通过测试的,哪个版本还存在问题,并对有问题的版本进行回滚。


为了提高持续集成的效率,当代码提交后,都会采用实时通知机制。目前的版本控制系统都提供了基于 WebHook 或基于消息的通知机制,当不同类型的事件发生后,就会通知注册方。


持续集成系统

虽然持续集成实践中并未要求一定要有个持续集成的工具。但工欲善其事必先利其器,使用持续集成工具可以达到事半功倍的效果。目前常用的持续集成工具有开源的 Jenkins,功能比较完备,基于插件体系可以与构建和部署领域的很多工具进行集成。


持续集成系统与版本控制系统集成时,一个关键点就是如何触发构建。下图是 Jenkins 自由风格流水线的界面,这里主要查看构建触发器这部分。Jenkins提供了多种触发策略来满足不同的需求。这里着重介绍其中的三个。

image.png

  • 定时构建:提供了类似 cron 的功能来定期执行。一般主要用于像每日构建/每周构建这样定期执行的构建。
  • Build when a change is pushed to GitLab:当 GitLab 发生变更后触发构建,该选项需要添加 GitLab 的 WebHook,当事件发生时才能进行通知。
  • 轮询 SCM:通过轮询的方式检查版本控制系统是否发生变更。该选项是一个成本很高的操作,因为每次轮询都需要 Jenkins 扫描整个工作空间并与服务器进行验证。


自动化测试

持续集成的目的是提前发现代码中存在的问题,保证软件是可工作的。如果没有全面的自动化测试,构建成功只能意味着应用程序能够编译通过,并不能保证软件的功能是正常的。因此,在持续集成流程中,自动化测试是必须的。有三类测试需要加入持续集成的流程中,分别是单元测试、集成测试和验收测试。


  • 单元测试:用于单独测试应用程序中某些小单元的行为,比如一个方法、一个函数。通常不需要启动整个应用程序就可以执行,而且也不需要连接数据库、文件系统和网络。


  • 集成测试:用于测试应用程序中几个组件的行为。与单元测试一样,通常也需要启动整个应用程序,但有可能需要连接数据库、访问文件系统或其他外部系统或接口。


  • 验收测试:用于验证应用程序是否满足业务需求所定义的验收条件,包含应用程序提供的功能,以及其他非功能性需求,如容量、安全性等。验收测试通常要将整个应用程序运行于测试环境之中。


开发人员的要求

为了做好持续集成,除了上面提到的一些工具作为支撑,对每个开发人员也提出了一些要求,主要体现在以下三个方面。


频繁提交

正如在开头提到,持续的含义是“随时”。我也给出了最恰当的频率:只要有人提交就需要进行集成。对于持续集成来说,开发人员需要做的就是频繁提交代码到版本控制库中一,每天至少提交一次。这样做有几个好处:


  • 提交得越频繁,越早收到集成的反馈;
  • 每次提交的变更很小,就很少会导致构建失败;
  • 即便是导致构建失败,也很容易知道是哪里的问题,很容易修复或者回滚。


在持续集成的实践中,建议采用“主干开发”的工作模式,因为这种模式才能真正做到持续集成。但在很多企业里都是采用 GitFlow 等基于分支的工作流模式来进行协同开发。因为每个开发人员都是在自己的分支上开发,并未与其他分支的代码实现实时集成。这里开发人员需要注意的是,不仅要频繁将代码提交到各自的分支,同时每天要至少一次将各自的分支合并到发布分支,进行全流程测试。


提交一个完整的任务

不要只为了频繁提交而随意提交代码,频繁提交不等于随意提交。要保证每次提交的内容都是有意义的,都是一个完整的任务。比如要添加一个查询家庭地址的接口,要把该功能开发完成后一次性提交,而不是接口写了一半就提交了。这个要求和之前谈到的限制在制品数量是有关系,如果同时并行的任务数太多,就会出现在一次提交里同时包含多个任务的代码。这种情况提交的代码会严重影响测试效果。


这种情况非常普遍,我正在处理一个 Bug 或者开发一个功能,已经改了很多文件。但这时需要处理其他更紧急的工作,如果在当前状态下修改就会出现同一次提交包含多个任务代码的问题。这里介绍一个方法来解决这个问题:可以使用 git stash 命令,保存当前对代码库做的更改,并恢复到上次提交的状态。当提交完穿插的任务后,再恢复到上一个更改的状态,继续完成该任务。这样就能保证每次提交都是一个完整的任务。


构建失败后立即修复

当某个团队成员提交代码后导致构建失败,说明本次提交影响了软件的整体质量。这个时候,整个团队都不能再继续提交代码了,而是先处理构建失败的问题。这个实践也是应用了丰田生产管理系统(TPS)中的“立即停止原则”。其含义是:当生产线上已经发现了问题,就应该立即停止来解决问题。如果问题没有得到有效解决还仍然是生产线保持运行,则会生产出更多的残次品。


同样的道理,对于软件团队来说,如果提交构建失败后没有立即修复,其他人再次提交新的代码,就一定会引起提交构建失败。那么,这次失败是上次失败导致的,还是新的代码导致的,就变得很复杂了。


目录
相关文章
|
5天前
|
运维 Devops jenkins
DevOps实践:自动化部署与持续集成的实现之旅
本文旨在通过一个实际案例,向读者展示如何将DevOps理念融入日常工作中,实现自动化部署和持续集成。我们将从DevOps的基础概念出发,逐步深入到工具的选择、环境的搭建,以及流程的优化,最终实现一个简单而高效的自动化部署流程。文章不仅提供代码示例,更注重于实践中的思考和问题解决,帮助团队提高软件开发和运维的效率。
|
8天前
|
运维 Devops jenkins
DevOps实践:自动化部署与持续集成的实现
【9月更文挑战第36天】本文通过深入浅出的方式,向读者展示了在现代软件开发中,DevOps如何通过自动化部署和持续集成提高开发效率和软件质量。文章不仅介绍了相关概念,还提供了实用的代码示例,帮助读者理解如何在实际工作中应用这些技术。
|
11天前
|
Devops jenkins 测试技术
DevOps实践:持续集成与持续部署(CI/CD)的实现之路
【9月更文挑战第33天】在软件开发的海洋中,DevOps是一艘能够加速航行、提升航程质量的巨轮。本文将作为你的航海图,指引你理解并实现DevOps文化中的核心环节——持续集成(CI)与持续部署(CD)。我们将从基础概念出发,逐步深入到实际操作,带你领略代码到部署的全过程。准备好扬帆起航,让我们共同探索如何通过自动化工具和流程优化,让软件交付变得既高效又可靠。
|
14天前
|
监控 Devops 测试技术
DevOps实践:持续集成与部署的自动化之路
【9月更文挑战第30天】在软件工程的世界中,DevOps已成为提升开发效率、确保软件质量和加快交付速度的关键策略。本文将深入探讨如何通过自动化工具和流程实现持续集成(CI)与持续部署(CD),从而优化软件开发周期。我们将从基础概念出发,逐步深入到实际操作,最终展示如何构建一个高效的自动化流水线,以支持快速迭代和高质量发布。
41 7
|
24天前
|
Devops jenkins Java
DevOps实践:持续集成和部署的自动化之旅
【9月更文挑战第20天】在软件开发的世界里,速度和质量是至关重要的。本文将带领读者踏上一场自动化之旅,深入探索DevOps文化中的两大支柱——持续集成(CI)和持续部署(CD)。我们将通过一个实际的案例,展示如何利用现代工具和技术实现代码从编写到部署的无缝转换,确保软件交付的高效性和可靠性。准备好让你的开发流程变得更加流畅和高效了吗?让我们开始吧!
|
15天前
|
Devops jenkins 测试技术
DevOps实践:持续集成与自动化测试的融合之道
【9月更文挑战第29天】在软件开发的快节奏竞赛中,DevOps如同一位智慧的舵手,引领着船只驶向效率与质量的彼岸。本文将揭开DevOps的神秘面纱,探索其核心理念如何通过持续集成(CI)和自动化测试的实践,实现软件开发流程的优化与加速。我们将一同见证代码从构思到部署的旅程,以及这一过程中的关键技术和工具如何协同工作,确保软件质量和交付速度的双重提升。
|
11天前
|
运维 Devops 测试技术
DevOps实践之路:从持续集成到自动化部署
【9月更文挑战第33天】在软件开发的海洋中,DevOps如同一艘航船,承载着敏捷开发与运维之间的桥梁。本文将带你领略DevOps的魅力,从持续集成的理念出发,穿越自动化测试的浪潮,直至自动化部署的港湾。我们将通过实际案例,探索如何构建一个高效、可靠的DevOps流程,让软件交付不再是梦魇,而是流畅的艺术。
|
2月前
|
敏捷开发 缓存 前端开发
阿里云云效产品使用合集之前端打包时npm安装卡住一般是什么导致的
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
2月前
|
敏捷开发 弹性计算 持续交付
阿里云云效产品使用合集之同一个主机部署是否支持下载多个制品
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
2月前
|
敏捷开发 监控 Java
阿里云云效产品使用合集之Codeup WebIDE环境下,如何使用通义灵码
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。