基于Jenkins的持续交付全流程设计与实践

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) {   
}

多配置项目

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

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

总结

将企业级持续集成的环境搭建起来本身并不难,难的是如何将整套体系与公司现有的开发流程相结合,考虑到受康威定律的影响,不同的组织对于新事物的接受程度总是不同的,所以难免需要做一些准备。

好文要顶 关注我 收藏该文  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++set容器-查找和统计

set查找和统计 功能描述&#xff1a; 对set容器进行查找数据以及统计数据 函数原型&#xff1a; 代码如下: #include <iostream> using namespace std; #include <set>//set查找和统计void test01() {//查找set<int >s1;//插入数据s1.insert(10);s1.inse…

C++set和multiset区别

区别&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <set>//set容器 和multiset容器的区别 void test01() {set<int >s;pair<set<int >::iterator, bool> ret s.insert(10);if (ret.second) {cout &…

.NET CORE(C#) WPF简单菜单MVVM绑定

阅读导航 本文背景 代码实现 本文参考 源码 1. 本文背景 WPF中垂直导航菜单大家应该都常用&#xff0c;本文介绍使用MVVM的方式怎么绑定菜单&#xff0c;真的很简单。 2. 代码实现 使用 .Net Core 3.1 创建名为 “MenuMVVM” 的WPF模板项目&#xff0c;添加两个Nuget库&…

C++pair对组的创建

pair对组创建 功能描述&#xff1a; 成对出现的数据&#xff0c;利用对组可以返回两个数据 两种创建方式&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <cstring>void test01() {//第一种方式pair<string, int>…

避免在 ASP.NET Core 3.0 中为启动类注入服务

本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇。 Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostingEnvironment VS IHostEnvironent - .NET Core 3.0 中的废弃类型 Part 3 - 避免在 ASP.NET Core 3.0 中为启动类注入服务&#xff08;本篇&…

C++set容器-内置类型指定排序

set容器排序 利用访函数&#xff0c;可以改变排序规则 一、set存放内置数据类型 代码如下&#xff1a; #include <iostream> using namespace std; #include <set>class Mycompare {public:bool operator()(int v1, int v2) {return v1 > v2;} };//set容器排序…

workman php 安装,workerman安装及遇到的问题解决

下面由workerman入门教程栏目给大家介绍workerman安装及遇到的问题解决方法&#xff0c;希望对需要的朋友有所帮助&#xff01;1、workerman安装workerman是php的一个socket框架&#xff0c;简化了socket编程&#xff0c;已经为很多企业所用&#xff0c;今天在centos的ngixphp下…

.NET CORE(C#) WPF亚克力窗体

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff1a;请网站留言&#xff0c; 如果对您有所帮助&#xff1a;欢迎赞赏。.NET CORE(C#) WPF亚克力窗体阅读导航本文背景代码实现本文参考源码1. 本文背景本文介绍使用FluentWPF控…

C++map容器-构造和赋值

map基本概念 map构造和赋值 功能描述&#xff1a; 对map容器进行构造和赋值操作 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; //map容器 构造和赋值 #include <map>void printMap(map<int, int> &m) {fo…

ABP框架v2.0 和 ABP商业版

ABP框架2.0版已经在本周公布.这篇文章解释了为什么我们发布了一个抢先主版本,和2.0版本中的变化.除了v2.0版本,我们很高兴地宣布ABP商业版,这是建立在开源ABP框架的之上的一套专业的模块,工具,主题和服务.ABP框架V2.0为什么2.0,而不是1.2&#xff1f;本来在V1.1.2发布后计划发布…

C++map容器-大小和互换

map大小和互换 功能描述&#xff1a; 统计map容器大小以及交换map容器 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <map>//map容器 大小和交换 void test01() {map<int, int>m;m.insert(pair<in…

分享一些提高逻辑能力的心得

大家好&#xff0c;我是Z哥。最近有个很明显的感受。就是随着年龄的增长&#xff0c;我越来越发现曾经一些我认为理所应当的事情&#xff0c;在现在看来是如此的傻&#xff0c;如此的没有逻辑。有一句话是这么说的。花半秒钟就看透事物本质的人&#xff0c;和花一辈子都看不清事…

php 配置远程调试,PHP Linux 环境下搭建 XDEBUG并配置远程调试

在网站 https://xdebug.org/download.php 找到对应PHP版本的XDEBUG下载&#xff0c;下载时选择source版本image获取下载地址## 下载打包的源码wget https://xdebug.org/files/xdebug-2.5.5.tgz解包tar zxvf xdebug-2.5.5.tgz进入解包后的源码目录cd xdebug-2.5.5执行 phpize 生…

CAP原理

定义在一个分布式系统&#xff08;指系统中的节点互相连接并共享数据&#xff09;中&#xff0c;当涉及读写操作时&#xff0c;只能保证一致性 (Consistency)、可用性 (Availability)、分区容错性 (Partition Tolerance)三者中的两个&#xff0c;另外一个必须被牺牲。一致性&am…

大学生开题报告php,php毕业设计开题报告

php毕业设计开题报告该频道涵盖有关于开题报告和毕业设计的论文范例,免费教你怎么写php毕业设计论文提供相关参考资料。一、研究背景1 基于英语新课程标准的要求。《英语课程标准》指出&#xff1a;必须正视学生外语学习基础和发展要求的差异&#xff0c;遵循外语学习的客观规律…

服务器应用服务为何卡顿?原来是内存耗尽惹的祸!

做过运维的朋友们都可能会遇到&#xff1a;服务器应用程序运行慢的问题&#xff0c;最终各部门找上门&#xff0c;。今天在这我跟大家分享一个案例及其解决办法。以前我跟很多朋友们也为这样的事情苦恼过&#xff0c;我的服务器内存可是64G啊&#xff0c;这都不够它吃的。后来我…

matlab 传感器的迟滞,MATLAB PI迟滞模型问题

之前我用matlab进行迟滞模型建模&#xff0c;误差非常大&#xff0c;我之前怀疑是自己的参数辨识出问题了&#xff0c;所以我用论文中的阈值向量和权重向量进行建模&#xff0c;输入数据也是用论文数据&#xff0c;但是出来的拟合的线误差非常大&#xff0c;和文献中相差太大。…

(2)MongoDB副本集自动故障转移原理(含客户端)

前文我们搭建MongoDB三成员副本集&#xff0c;了解集群基本特性&#xff0c;今天我们围绕下图聊一聊背后的细节。默认搭建的副本集均在主节点读写&#xff0c;辅助节点冗余部署&#xff0c;形成高可用和备份&#xff0c;具备自动故障转移能力。集群心跳保活集群每个节点以周期性…

matlab如何使用cu文件,Matlab编译cuda的.cu文件

matlab函数&#xff0c;大体首先是用nvcc命令生成.o文件&#xff0c;然后用mex链接对应库文件&#xff0c;生成动态链接库(.mexw64等)。测试环境&#xff1a;1) Windows x64 matlab cuda 5.5 vs20122) Ubuntu 12.04 amd64 server matlab gcc cuda 5.5windows用户需要根据…

C++map容器-查找和统计

map查找和统计 功能描述&#xff1a; 对map容器进行查找数据以及统计数据 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <map> //map容器 查找和统计void test01() {//查找map<int, int >m;m.insert(p…