CODING 敏捷实战系列课第四讲:从头搭建持续集成 DevOps 流水线
《从头搭建持续集成 DevOps 流水线》由资深敏捷教练、极限编程学院高级讲师、CODING 特邀敏捷顾问李小波老师主讲,将基于 CODING 展示如何编写 Jenkinsfile 搭建 CI/CD 流水线,包括单元测试,端到端测试,代码规范检查,制品库,Docker 化部署。
大家好,今天课程的主要内容为如何从头搭建 DevOps 流水线以及其在研发工作中的意义,最后是 DevOps 流水线实践与敏捷开发的关系的总结。
最开始是在极限编程里提出了持续集成,然后 ThoughtWorks 又提出了持续交付,之后又提出了DevOps 这个概念,为什么要做这些呢?我认为原因是随着时间的增长,生产力会不断的下降。团队刚开始时效率很高,从 0 到 1,功能上线很快,但是到了后期速度就会越来越低,直到最后开发停滞。系统开发的后期往往会出现三个难点:第一,增加新特性难。随着系统功能的累积,会出现很多重复的代码以及不合理的设计,导致增加一个新特性时要改的地方非常多,改动成本非常高;第二,修复缺陷难。用户可能会报一些缺陷或 Bug,但是因为代码太乱、太复杂导致很难定位到缺陷;第三,引出新的缺陷。做新 Feature 时,很容易出现打地鼠的现象,按下一个 Bug 结果又冒出来三个 Bug,给团队带来困境。
出现这些现象的原因首先是在需求演变的过程中,有的代码会不断地腐坏,方法会越来越长,类会变得越来越大,代码出现大量的重复。虽然有些团队会制定代码规范,但在实际应用中,可能基本上都在 Word 或 PDF 里“躺着”,检查执行难以长期坚持。
其次是架构也会腐坏。项目开始时架构师通常会根据业务设计好架构,有多少个模块、对象,分到几层,哪层可以调,哪层不能调,怎么依赖关系,这些都会很清楚,但在不断的演变过程中,架构往往会变得乱七八糟。
戴明(William Edwards Deming)提出了质量内建的概念,即产品的质量在建设过程中就已经嵌入,并不是靠后期的检测来发现的。后期的检测并不能增进代码质量,也不能提升产品质量,问题发现的越早修复的成本越低。所以我们希望每一次往代码库提交代码时,都能够马上获得反馈:这次修改是好的还是不好的,是不是增加了重复的代码,是不是降低了测试覆盖率,是不是破坏了某一些功能等等。有了这样的评判标准,就能够始终保证每个人每次提交代码都是在产品上增加价值,而不是破坏它。在这个背景下就引入了流水线这个概念。
流水线是一个隐喻,意思是将软件研发的各个环节衔接起来。我认为流水线在研发管理过程中扮演了三个角色:不辞辛劳的临时工、铁面无私的守护者以及快速精准的操作员。
流水线是不辞辛劳的临时工。现在的构建流水线都可以按需创建。比如说 CODING,这么多的企业在用它的持续集成功能,不可能给每一个用户分配固定的计算、存储等资源。如果要能线性的增长,策略应该是当用户需要构建时会按需进行创建,并且用完之后进行销毁。从这一点上看,流水线就很像一个临时工。除此之外,流水线还可以不厌其烦地做重复的事情,尤其是持续集成的团队每天都要提交很多次代码,每一次提交都人工做一次检查就很痛苦,但机器就能重复机械运动。
流水线是铁面无私的守护者。首先是代码规范。很多开发团队的代码规范都“活”在 Word 或 PDF 里,即使有资深教练或者技术 Leader 偶尔会做一些代码评审,这种执行力度也是远远不够的。但是通过集成到流水线中的方式,比如指定一个方法不能超过多少行,一个类不能超过多少行,代码重复率不能超过多少,代码的宽度及命名等,进行自动化、标准化的检测,就可以有效的保证代码规范的落地;第二是测试覆盖率。在日常的开发工作中会有单元测试、组件测试、接口测试、集成测试、端到端测试等多种测试,每一次提交代码都需要检查测试覆盖率有没有下降。但很多团队这一块是缺失的,他们在流水线上只是做了构建、打包、部署等动作,并没有跑测试覆盖率,而是靠大规模的手工测试来保证质量,导致无法快速迭代;第三是架构约束。代码一般有分层,每一层里应该放什么文件,哪个文件能够调哪个文件,这些都是有约束的,需要一套自动化的机制来保证落地;其次还有安全性检查。比如做 Web 开发会引入一些第三方的开源代码,这些开源代码往往会有安全缺陷,需要在每次引入新内容时进行安全性检查。
流水线是快速精准的操作员。越复杂的系统,环境就越多,包括开发联调环境、测试环境、预发布环境等,到正式的环境还会有多个实例。每个环境上访问数据库的 URL 不一样,访问其他服务的环境也会不一样,如何保证在操作过程中都不出错?可以依靠流水线来标准化、流程化、自动化地完成这些动作,每次代码提交时都检查规范,针对不同的环境打出不同的包,持续的部署到不同的环境上面。
那么如何搭建一条流水线?有一种方式叫做流水线即代码(Pipeline as Code),即把流水线放到代码里。我认为这样做的好处是版本化,传统的搭建方式问题在于操作没有记录,也无法强制 Review,当一台服务器挂掉,换一台服务器时需要把原来流水线的配置重新操作一遍。如果将流水线变成代码,就可以跟踪及重复创建,提高生产效率。另外补充一点,流水线在构建时主要有两种方式,一个叫声明式,一个叫指令式。声明式就是规定好环节与步骤,需要怎样的东西。而指定式需要写很多的条件判断,是逻辑式的,维护成本也会高一些,所以声明式是目前普遍采用的一种方式。
一条典型流水线应该包含四个关键环节。第一是构建。前端、后端的代码都需要编译,前端比如 HTML、JS、CSS 等,可能还会用到一些模板,需要做编译工作将其转成浏览器能够支持的格式;第二是检查。编译完成之后需要检查代码是不是符合规范,是不是有很多的重复代码,重复率超过了多少等等;第三是测试。测试环节很重要,会影响团队对于产品发布的信心。这里讲一个测试金字塔理论:底层是大量的单元测试,中间是组件测试或者接口测试,顶部是端到端测试。因为大量的逻辑都是在各种 If else 分支里,单元测试可以覆盖到这些分支,那么上层的测试就不需要再覆盖下层已经覆盖过的逻辑了。而上层测试的价值在于把这些代码集成起来,站在用户的角度去使用它,看看能否正常工作。上层和下层的测试关注点不一样,解决的问题也不一样;第四是部署。最后需要构建镜像,并推到制品库里面去,更新服务器,做完这一系列的事情之后,流水线实例就会销毁。
最后总结一下,为什么会衍生出 DevOps 实践及其跟敏捷开发的关系:
第一,我们最重要的目标是通过持续不断地及早交付有价值的软件使客户满意。我认为这跟敏捷是一脉相承的。敏捷的原则里说可工作的软件高于详尽的文档,客户更希望看到的是可用的软件,而不仅仅是文档说明,但是由于开发过程的不透明,造成了客户喜欢做微观管理的现象,同时也会让开发团队变得很被动。敏捷里有个价值观叫尊重,这种尊重是需要团队自己去赢得的。通过建立一套流程,提高开发过程的透明度,从而建立客户与团队之间的信任。另外跟敏捷原则相契合的一点是响应变化高于遵循计划。这不是一句口号,而是一种能力,它包含:项目管理能力、需求管理能力、配置管理能力以及质量保障能力。这四种能力建设起来之后,团队才能拥有响应变化的能力。持续集成、自动化测试、自动部署等这些核心能力,搭配上代码规范、CodeReview、TDD等这些实践,才能真正提升开发团队的实力,而不是仅仅把 Scrum 导入进来,开开计划会、站立会就行了。
第二,可工作的软件是进度的首要度量标准。不是每天站会或者每周写个邮件告诉客户这周完成了多少工作,而一定是部署完成后,变成了可以看到的、可以体验的功能才算是真正的进度。
第三,坚持不懈的追求技术卓越和良好的设计,敏捷能力由此增强。开发团队拥有了代码规范检查、自动化测试等这些质量门禁以后,才有底气去不断的做优化,得到可持续的、快速迭代的速率。实践都会随着技术的变化而变化,团队能力也在持续的变化,但能不能持续地保持敏捷,那就要看价值观、原则是不是能够持续地符合。
CODING 敏捷实战系列课第四讲:从头搭建持续集成 DevOps 流水线的更多相关文章
- CODING 敏捷实战系列课第五讲:敏捷中国史
敏捷软件开发方法自 2001 年传入中国以来,历经十多年的发展变迁,目前已经成为国内 IT 企业主流的研发管理方法.敏捷方法的传播和发展历程,是中国 IT 行业发展的剪影.CODING 特邀敏捷顾问. ...
- CODING 敏捷实战系列课第二讲:Scrum 敏捷项目管理核心要素之 3355
Scrum 是敏捷开发流派中最著名和最落地的一支,全球 70% 以上公司的敏捷转型都是以 Scrum 起步.CODING 特邀敏捷顾问.CST & CTC 认证敏捷教练申健老师将在本课程< ...
- CODING 敏捷实战系列课第三讲:可视化业务分析
业务分析处在开发过程的上游,提高业务分析的质量,可以减少后续开发.测试和集成过程中的反复确认,场景遗漏.采用可视化的业务分析工具箱可以大幅度避免文字版的业务需求描述所带来的不够完整,有误解等问题.CO ...
- Python接口测试实战5(上) - Git及Jenkins持续集成
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- katalon系列十一:Katalon Studio在Jenkins持续集成
以下在WIN10上运行正常.安装准备:一.安装Katalon Studio二.安装Jenkins三.获取Katalon命令行运行命令:点击工具栏的‘Build CMD’按钮,选择测试集以及其他选项:选 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【四】——实现模型工厂,依赖注入以及格式配置
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在上一篇中,我们已经初步开始使用Web Api了,但同时出现了一些很多不足之处,本章我们就着 ...
- Vue3实战系列:Vue3.0 + Vant3.0 搭建种子项目
最近在用 Vue3 写一个开源的商城项目,开源后让大家也可以用现成的 Vue3 大型商城项目源码来练练手,目前处于开发阶段,过程中用到了 Vant3.0,于是就整理了这篇文章来讲一下如何使用 Vue3 ...
- pytest系列(四)- pytest+allure+jenkins - 持续集成平台生成allure报告
pytest是什么 pytest是python的一款测试框架,拥有unittest的功能并比它更丰富. allure是什么 有非常多的优秀的测试框架,但却是有非常少优秀的报告工具可以展示非常清楚的用例 ...
- gitblit系列七:使用Jenkins配置自动化持续集成构建
1.安装 方法一: 下载jenkin.exe安装文件 下载地址:https://jenkins.io/content/thank-you-downloading-windows-installer/ ...
随机推荐
- STL入门大全(待编辑)
前言:这个暑假才接触STL,仿佛开启了新世界的大门(如同学完结构体排序一般的快乐\(≧▽≦)/),终于彻底领悟了大佬们说的“STL大法好”(虽然我真的很菜www现在只学会了一点点...)这篇blog主 ...
- 使用binlog2sql工具来恢复数据库
(一)binlog2sql介绍 binlog2sql是国内MySQL大佬danfengcao开发,许多MySQL爱好者参与改进的一款MySQL binlog解析软件.根据不同选项,可以得到原始SQL. ...
- DataTable运用
DataTable dataDis.AsEnumerable().Sum(bu => bu["QtyPlan"].ConvertInt32()); ndata.TDefSty ...
- Websec level 30
前言 昨天在易霖博搞的网络安全与执法竞赛看到的一道web题,实际上就是用两个原题凑起来的.. 不过后面的一关没见过这里简单记录一下 第一关 打开是个登录界面,和BJDCTF的简单注入一模一样,连密码都 ...
- python爬虫+正则表达式实例爬取豆瓣Top250的图片
直接上全部代码 新手上路代码风格可能不太好 import requests import re from fake_useragent import UserAgent #### 用来伪造爬头部信息 ...
- 深入理解Java枚举
深入理解Java枚举 重新认识Java枚举 老实说,挺羞愧的,这么久了,一直不知道Java枚举的本质是啥,虽然也在用,但是真不知道它的底层是个啥样的 直到2020年4月28日的晚上20点左右,我才真的 ...
- 2019-2020-1 20199310《Linux内核原理与分析》第三周作业
1.问题描述 计算机的3大法宝是存储程序计算机,函数调用堆栈和中断机制,存储程序计算机已经在上一个博客中进行具体描述,本文将在剩下两方面出发对操作系统是如何工作的进行学习和探讨. 2.解决过程 2.1 ...
- webform 最后的黄昏之力
前言 现在有人谈起webform 一般都会说这种技术已经过时了,毫无用处. 因为我们在日常开发中已经不会去开发哪种几个简单的网页的程序,我们的业务更加复杂,这种拖动式的过于死板. 但是是否毫无用处呢? ...
- 自定义parallelStream的thread pool
目录 简介 通常操作 使用自定义ForkJoinPool 总结 自定义parallelStream的thread pool 简介 之前我们讲到parallelStream的底层使用到了ForkJoin ...
- Libra教程之:Libra testnet使用指南
文章目录 Libra testnet网络 下载和安装Libra 编译Libra client并连接到Testnet网络 创建两个A和B的两个账号 检查libra cli Client是否运行 创建A的 ...