1 从理论开始

什么是DevOps?

近年来,随着DevOps理念的逐渐深入人心,企业逐渐意识到从看似重复的手工劳动中实现自动化流程处理,对于提高企业劳动生产力已经非常重要,尤其是面向互联网的开发者,往往每次上线时,最大的挑战并非需求的走查或测试和改bug,而是由于发布的流程不够规范,将成果发布到目标环境后可能造成的配置错误或引发其他已知未知问题所造成的额外工作量,使得生产环境的发布流程总会存在不顺利。

而DevOps则致力于统一整合软件开发和软件运维,其特点是强烈倡导对构建软件的所有环节(从集成、测试、发布到部署和基础架构管理)进行全面的自动化监控。目标是缩短软件开发周期,提高部署频率和更可靠的发布,与业务目标保持一致。

在实际操作过程中,对于许多公司而言,开发者和运维者并没有明确的界限,而且即便将运维与开发的岗位职责分开了,也并非意味着双方的职业发展方向将大不相同。实际上在实际操作过程中,开发人员和运维人员依然会使用相同的工具、统一的流程、一致的管理思想,并通过一系列管理手段和工具实现流程的优化。

什么是持续集成和持续交付?

持续集成(Continuous Integration)与持续交付(Continuous Delivery)也正是DevOps中最为基础的两种企业级研发和交付活动。

持续集成来源于敏捷项目管理思想,其核心是团队成员应该经常集成他们的工作,通常每天要求集成一次,当然也可以要求团队成员每天集成多次。每次集成之后,会通过持续集成工具自动运行自动化的构建手段(例如编译、单元测试、集成测试、系统测试),并对集成后的成果进行验证,从而实现了企业管理流程中尽早的发现未知问题的目标。而在传统的软件交付中,可能会将所有问题积压到系统整体测试或甚至UAT(用户验收测试)环节,使得软件的测试时间被拉长,甚至使得软件的问题流入到客户现场,让客户成为小白鼠的情况时有发生。

实际上而言,看似简单的集成,却并非简单,他应该是企业管理过程中的一项铁律,只有严格执行,才能确保软件时刻处于可用状态;否则就意味着所谓交付过程中完成进度的百分之多少,只不过是一个虚无缥缈的空口白话。

持续集成往往离不开持续交付,在乔梁老师翻译的《持续交付》一书中,作者Jez Humber说:持续交付是一种能力,也就是说,能够以可持续的方式,安全快速的把代码变更(包括特性、配置、缺陷和试验)部署到生产环境中,让用户使用。这本书的作者也在书的最后一章中指出:它(持续交付)不仅仅是一种新的软件交付方法论,而且对依赖软件的业务来说,也是一种全新的范式。

持续交付与持续部署看似类似,其实有所区别,前者往往是指将环境推送到用户面前,使用户能够触及和使用它们;而部署则仅仅只是把软件包安装到目标计算机上,用户可能还无法直接使用。

对于面向互联网的软件企业来说,往往都已经在过去若干年间已经建立了一套完整的持续集成/持续交付流程,但对于某些处于飞速发展期的企业来说,依然相对而言后知后觉,主要是由于企业过去飞速发展的背后所依托的人力物力资源,能够足以保证企业的产出能够适应企业发展的需要,然而随着团队规模的发展赶不上企业业务发展的需要时,重复劳动和看似毫无价值的等待期、后期积压的测试任务、无法有效度量的软件功能实现,实质上也会造成企业的管理成本进一步提高。

从哪里可以获得系统的方法论?

对于需要搭建一套完整环境的开发者来说,网上资料很齐全,本文也试图尽可能的对各方面的内容进行综述,努力为开发者提供一个开箱即用的操作流程,但是对于那些想系统的学习持续交付或DevOps领域的知识的开发者来说,你其实不仅仅满足于把环境搭起来,那么你应该看看书。

在持续集成和持续交付领域有大量优秀的作品,而我觉得来自乔梁老师的作品《持续交付2.0》堪称精品,乔梁老师是一位经验丰富的行业专家,在他的职业生涯中积累了与该领域相关非常丰富的产品研发经验,他也身体力行的参与到许多企业的持续交付流程优化过程中,这些经验都让他能够从更全面的视角来分析持续交付的问题。在这本书中介绍了许多直接拿来就可以使用的管理方法、项目案例、工具,能够让有需求在该领域有所作为的开发者带来不少思考。

实质上对于一家要实践持续集成/持续交付的企业来说,将工具搭建完成并非核心难点,难点依然在于如何使用敏捷项目管理的思想,实现软件的细粒度任务拆分,并能够对单个任务进行更好的测试,或许TDD是一种不错的模式,但是却可能给开发者的基础技能提出了更高的要求,这将导致TDD无法落地。

如何快速验证产品需求?在《持续交付2.0》中提出的了一系列的方法,例如装饰窗、最小可行特性法、特区法、定向搜索法、稻草人法、、最小可行产品法等六种方法,通过建立快速验证模型,提高软件从需求到实现的整个流程,能够为企业带来不少便利。

而在研发阶段,可以采用特性分支和特性开关的手法,利用git源代码管理工具分支的妙处,将需求和代码有机的耦合在一起,同时又依托项目管理工具,实现从需求=》实现=》发布的完整闭环,从而为需求的验证提供了双保险;特性开关我最早在刘华老师的《猎豹行动-敏捷转型》一书中看到,通过使用软开关的形式,避免未开发完成的提前上线造成巨大的风险,而在这边书中也同样提到了这样的方法。在.NET中同样也可以使用特性分支组件,后期我将尝试一下。

而对于如何减少等待期,作者提到的方法是:

1、通过“拉动”让价值流动起来,例如,如果是一个生产线的滞留,通过扩大瓶颈的处理能力,让更多的需求能够快速交付,这种手法看似能够临时提高环节处理能力,保障团队的产出,但是显然不是个良好的措施,更合理的措施就是根据下游的生产能力来确定上游的处理能力,由下游来拉动上游的需求。这客观上要求将任务和需求的粒度进一步均匀化,将需求划分成更加易于执行、工作量类似的小需求,使得开发过程更加平滑。

2、任务自助化:也就是让团队掌握某些通用技能,以便在其他人员阻塞时,能够同步完成相关任务,避免了某些关键任务阻塞造成了整体流程的滞后。

在此我就不过多描述书中的精华了,有兴趣的可以入手一本,绝对物超所值。

2、总体流程和环境部署

接下来我将进入本文的主题,首先我将构建一个简单的企业级持续集成/持续交付的管理流程,然后再对流程的实现过程进行较为详细的介绍。

流程图

![图片](

)

在这个流程中,使用了master/dev的分支模式。

1、对于dev分支提交的代码,经过代码编辑、静态代码扫描、自动化单元测试的流程,在运行通过后,有测试人员进行代码的测试,并在代码测试通过后,通过pull request提交给master分支的审查人员进行代码检查和合并。

2、测试人员对dev提交的代码进行确认,并由master分支代码审查人员进行代码审查,通过后对代码进行确认,并生成用于发布的生成包。

涉及的组件和说明

在流程中,使用了以下工具,依次安装即可。

1、安装OpenJDK

2、安装Jenkins和相关插件

3、安装PostgresDb

4、安装SonarQube

5、安装dotnetsdk3.1

6、安装git

7、安装nexus包管理器 for windows版用以实现包管理。

8、安装Qy Wechat Notification或HTTP Request 用以实现企业微信提醒。

好吧,环境安装就不介绍了。。

安装补充说明

1、其中jenkins安装的版本为2.190.3,OpenJDK安装的版本为openjdk12.0。安装完jenkins和openjdk后,需要进行环境变量的设置。

2、SonarQube安装的版本为7.9.1,根据官方网站的说明,推荐使用的数据库包括:sqlserver\oracle\postgresdb,在7.9.1和更高版本中,已经不再推荐使用mysql。

3、SonarQube默认使用了基于H2内存数据库的嵌入式数据库,可以在测试环境下使用,但是不建议用于生产环境。

5、安装完sonarqube、和数据库后,需要修改sonarqube/conf/sonar.properties文件中的数据库配置地址,并将sonarqube的服务重启。

![图片](

)

在windows系统中,点击sonarqube-xxx\bin\windows-x86-64文件夹中的InstallNTService.bat用以安装SonarQube的服务,而StartNTService.bat则用于启动SonarQube的应用服务。如果数据库配置失败,则SonarQube会启动失败,并提示以下错误:

[sonar-1510653879773] exception caught on transport layer [[id: 0x346b46fb, /127.0.0.1:59330 => /127.0.0.1:9001]], closing connection

java.io.IOException: An existing connection was forcibly closed by the remote host

6、由于使用了自行搭建的Nuget包源管理器,所以在进行构建时,会提示错误,jenkins会使用

Jenkins的项目类型

在jenkins中提供了自由风格、单流水线、多分支流水线、多配置项目等不同类型的项目,可以根据实际情况进行取舍,在本人的尝试过程中,分别总结了三种不同类型的项目可适用的场景:

自由风格项目

操作流程简单,无需配置groovy脚本,即可简单的完成项目的自动化构建。

在自由风格模式的项目中,实现代码编译的过程主要在构建窗口中,主要使用dotnet -相关命令来完成。包括:

1、dotnet restore 还原依赖包。

2、dotnet build 编译

3、dotnet publish -o ./bin/release 发布到指定目录下。

4、如果需要使用sonarqube来进行静态代码检查,需要在服务器上安装dotnet-sonarscanner组件,这个组件是基于.net core构建的静态代码检查组件,安装的命令为:

dotnet tool install --global dotnet-sonarscanner --version 4.8.0;

5、如果采用.net framework 传统框架,则可以继续使用原来的SonarScanner.MSBuild.exe组件进行代码检查结果的上传。

6、如果需要在自由风格项目中使用powershell脚本,可以在jenkins=》插件管理=》可用插件中搜索powershell即可。

单流水线项目

单流水线项目:可适用于只有一个分支和一套环境需要部署时的项目构建,其发布流程需要使用groovy脚本来实现。点击查看pipeline的语法

1、在流水线项目中,都在项目文件的根目录中添加jenkinsfile文件(无扩展名)作为jenkins编译时的脚本文件,而这个文件的脚本语法采用groovy语言,并支持开发者按照脚本语言进行扩展。

2、在单流水线项目中不支持groovy的分支判断条件,支持逻辑比较简单的脚本。

3、与编译有关的结构均写在jenkinsfile中,因此jenkins的UI界面可以理解为配置与项目相关的环境变量信息。

4、可以在jenkinsfile中定义输入的参数,例如:

parameters{

        string(name:'ProjectName', defaultValue: 'Enter Your ProjectName', description: 'Enter your project name here')

        string(name:'Contact', defaultValue: '"@All","xxx"', description: 'Enter Your Contract') 

        string(name:'RepoUrl', defaultValue: 'https://xxx.com/xxx/xxx.git', description: ' gitee代码路径')

}

在jenkins界面中,可以显示成

![图片](

)

在具体场景下就可以通过jenkins界面传入相关参数进行编译的测试了。

多流水线项目

多分支流水线项目:使用于一个仓库下各分支不同环境需要部署时的项目构建,其发布流程也需要使用groovy脚本实现。

1、多流水线项目支持使用分支判断条件的语法,因此可以使用的场景更多。

2、其他的总体上和单分支流水线差不多,此处就不在赘述了。

以下编写了一个简单的示例,仅供参考。

pipeline{
    agent any 
    parameters{
        string(name:'Contact', defaultValue: '"@All",""', description: 'Enter Your Contract') 
        string(name:'RepoUrl', defaultValue: '', description: ' 代码路径')
        string(name:'SonarUrl', defaultValue: 'http://xxx:9000', description: ' sonar代码路径')
    } 
    stages {
        stage('When Master') { 
            when {
                expression {BRANCH_NAME==~/(master)/}
            } 
           steps{       
               checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxx', url: params.RepoUrl]]])
            }
        }
        stage ("When Dev"){
            when {
                branch 'dev'
            } 
            steps{ rojectName}") 
            }
        } 
        stage("test"){
            when{
                expression{return true}
            }
            steps{
                echo "OK"
            }
        }    
        stage('Web Dev Build') {
            steps{
            }
        } 
    }
    post{
      success{
        SendToWeChatWork("CI Task success,ProjectName is ${params.ProjectName}") 
        echo 'Publish Success'
      }
      failure{
        SendToWeChatWork("CI Task Failure,ProjectName is ${params.ProjectName}") 
        echo 'Publish Failure'
        }
    }
}
def SendToWeChatWork(content) {   
}

多配置项目

如果组件代码需要在不同的配置、不同的环境下重复部署,其基本逻辑类似,只是配置不同,就可以使用多配置项目。

好吧,我就没有尝试了,因为我已经用了多流水线项目来实现了。在这篇示例中对多配置项目有比较详细的用法,需要可自取。

总结

将企业级持续集成的环境搭建起来本身并不难,难的是如何将整套体系与公司现有的开发流程相结合,考虑到受康威定律的影响,不同的组织对于新事物的接受程度总是不同的,原有组织或许已经习惯了基于手工拷贝再部署的模式,而目前采用这种持续集成、持续发布的模式,会出现哪些问题,我已经做好了准备了。

基于Jenkins的持续交付全流程设计与实践的更多相关文章

  1. 基于Jenkins的持续交付方案

    简介 Jenkins是开源的自动化编译.测试.部署的Web应用程序一个持续性交付应用 Jenkins的优势 1.Jenkins在国内的开发者中认可度较高,很多创业公司的自建持续交付系统的选择大部分都是 ...

  2. 基于Jenkins的开发测试全流程持续集成实践

    今年一直在公司实践CI,本文将近半年来的一些实践总结一下,可能不太完善或优美,但的确初步解决了我目前所在项目组的一些痛点.当然这仅是一家之言也不够完整,后续还会深入实践和引入Kubernetes进行容 ...

  3. CI Weekly #14 | 如何搭建合适的持续交付开发流程?

    时隔 10 个月,flow.ci 开始正式收费上线.为感谢对我们的内测支持,所有内测用户可继续免费使用基础版 30 天,截止至 3 月 15 日失效.欢迎随时告诉我们你对收费版 flow.ci 的反馈 ...

  4. 基于 Jenkins+Docker+Git 的CI流程初探

    在如今的互联网时代,随着软件开发复杂度的不断提高,软件开发和发布管理也越来越重要.目前已经形成一套标准的流程,最重要的组成部分就是持续集成(Continuous Integration,CI)及持续部 ...

  5. 还在手动部署jar包吗?快速掌握Jenkins安装,教你使用Jenkins实现持续交付

    Jenkins Jenkins: 开源软件项目 基于Java开发的一种持续集成工具 用于监控持续重复的工作 旨在提供一个开放易用的软件平台, 便于软件的持续集成 基于Docker安装Jenkins 与 ...

  6. SonarQube+Jenkins,搭建持续交付平台

    前言 Kurt Bittner曾说过,如果敏捷仅仅只是开始,那持续交付就是头条! "If Agile Was the Opening Act, Continuous Delivery is ...

  7. 基于Jenkins的持续集成CI

    CI(continuous integration)持续集成 一次构建:可能包含编译,测试,审查和部署,以及其他一些事情,一次构建就是将源代码放在一起,并验证软件是否可以作为一个一致的单元运行的过程. ...

  8. docker4dotnet #5 使用VSTS/TFS搭建基于容器的持续交付管道

    在过去的几篇d4d系列中,我给大家介绍了如何使用docker来支持asp.net core的应用开发,打包的场景.Asp.net core的跨平台开发能力为.net开发人员提供了使用容器进行应用开发的 ...

  9. 【转】基于Jenkins实现持续集成【持续更新中】

    知识预览 持续集成 Jenkins安装 Jenkins插件 Jenkins配置 Jenkins备份与恢复 发布PHP项目 SVN 发布Maven项目 按版本发布 远程管理 War文件部署设置 任务 J ...

随机推荐

  1. Android Studio(九):引用jar及so文件

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  2. hdu 4146 Flip Game

    Flip Game Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  3. 洛谷P3957 跳房子 题解 二分答案/DP/RMQ

    题目链接:https://www.luogu.org/problem/P3957 这道题目我用到了如下算法: 线段树求区间最大值: 二分答案: DP求每一次枚举答案g时是否能够找到 \(\ge k\) ...

  4. H3C 在网络中的正确位置配置ACL包过滤

  5. java 多线程安全问题的解决方法

    三种方法: 同步代码块: synchronized(obj) { //obj表示同步监视器,是同一个同步对象 /**..... TODO SOMETHING */ }   同步方法 格式: 在方法上加 ...

  6. java super关键字和调用父类构造方法

    表示父类对象的默认引用 如果子类要调用父类被覆盖的实例方法,可用super作为调用者调用父类被覆盖的实例方法. 使用super调用父类方法 使用super调用父类的构造方法 调用构造方法 本类中调用另 ...

  7. Cookie内不能直接存入中文,cookie转码以及解码

    如果在cookie中存入中文,极易出现问题. js在存入cookie时,利用escape() 函数可对字符串进行编码, 用unescape()进行解码 顺序是先把cookie用escape()函数编码 ...

  8. 【codeforces 761A】Dasha and Stairs

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. Layout 实现三栏布局的几种方法

    https://github.com/ljianshu/Blog/issues/14    布局参考 https://github.com/ljianshu/Blog/issues/38  响应式那点 ...

  10. cccc初赛 L3-003 长城

    L3-009. 长城 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 邓俊辉 正如我们所知,中国古代长城的建造是为了抵御外敌入侵.在长 ...