持续集成与持续部署(二)——持续集成之组成要素、应用场景 & 持续集成相对传统工作流的优势和问题
持续集成组成要素
一个最小化的持续集成系统需要包含以下几个要素:
- 版本管理系统: 项目的源代码需要托管到适合的版本管理系统中,一般我们使用git作为版本控制库,版本管理软件可以使用github、
gitlab
、stash等。 - 构建脚本&工具: 每个项目都需要有构建脚本来实现对整个项目的自动化构建。比如Java的项目就可以使用gradle作为构建工具。通过构建工具实现对编译、静态扫描、运行测试、样式检查、打包、发布等活动串起来,可以通过命令行自动执行。
- CI服务器: CI服务器可以检测项目中的代码变动,并及时的通过构建机器运行构建脚本,并将集成结果通过某种方式反馈给团队成员。
应用场景
-
打包平台
常见的打包,Java应用(Gradle/Maven)、Nodejs前端应用(npm/yarn)
移动端打包:Android/iOS
-
测试平台
接口测试
自动化测试Robotium、Testlink
单元测试junit
性能测试Jmeter
-
自动部署
FTP
Shell
Tomcat/Dokcer
Kubernetes/Rancher/Cluster
-
持续集成
Git: gitlab github gitee等
Jenkins/TravisCi/CircleCI
Docker
工作流
传统的工作流
参与人员:开发、项目经理、测试
主要流程:
- 项目一开始是先划分好模块,
分配模块
给相应的开发人员; - 开发人员
开发好
一个模块就进行单元测试
; - 等所有的模块都开发完成之后,由项目经理对
所有代码进行集成
; - 集成后的项目由项目经理
部署到测试服务器
上,被交由测试人员进行集成测试; - 测试过程中出现 Bug 就提把问题
记录
进行Bug
列表中; 项目经理分配 Bug
给相应的责任人进行修改;- 修改完成后,项目经理
再次
对项目进行集成,并部署
到测试服务器上; - 测试人员在下一次的集成测试中进行
回归测试
; - 通过通过之后就
部署到生产环境
中; - 如果测试不通过,则重复上述“分配 Bug -> 修改 Bug -> 集成代码 -> 部署到测试服务器上 -> 集成测试”工作。
这也是传统的瀑布式开发模型,请参考:软件开发模式对比(瀑布、迭代、螺旋、敏捷)
带来的问题:
-
重复性劳动,无效的等待变多
重复的进行发布部署。
流程上:有可能开发在等集成其他人的模块;测试人员在等待开发人员修复 Bug;产品经理在等待新版本上线好给客户做演示;项目经理在等待其他人提交代码。不管怎么样,等待意味低效。
自动化部署工作可以解放了集成、测试、部署等重复性劳动,而且机器集成的频率明显可以比手工的高很多。
-
很晚才发现缺陷,并且难以修复。
实践证明,缺陷发现的越晚,需要修复的时间和精力也就越大。从上一个可工作的软件到发现缺陷之间可能存在很多次提交,而要从这些提交中找出问题并修复的成本会很大,因为开发人员需要回忆每个提交的上下文来评估影响点。
-
低品质的软件,软件交付时机无法保障
由于集成时每次包含的代码很多,所以大家的关注点主要都是如何保证编译通过、自动化测试通过,而往往很容易忽略代码是否遵守了编码规范、是否包含有重复代码、是否有重构的空间等问题。而这些问题又反过来会影响今后的开发和集成,久而久之集成变得越来越困难,软件的质量可想而知。
-
项目缺少可见性
某些项目,程序会经常需要变更,特别是敏捷开发的实践者。由于产品经理在与客户交流过程中,往往实际的软件就是最好的原型,所以软件会被当作原型作为跟客户交流的工具。当然,客户最希望的当然是客户的想法能够马上反映到原型上,这会导致程序会经常被修改的。那么也就意味着“分配 Bug -> 修改 Bug -> 集成代码 -> 部署到测试服务器上 -> 集成测试”工作无形又爆增了。
常见的工作流
该系统的各个组成部分是按如下顺序来发挥作用的:
-
开发者检入代码到源代码仓库。
-
CI系统会为每一个项目创建了一个单独的工作区。当预设或请求一次新的构建时,它将把源代码仓库的源码存放到对应的工作区。
-
CI系统会在对应的工作区内执行构建过程。
-
配置如果存在)构建完成后,CI系统会在一个新的构件中执行定义的一套测试。完成后触发通知(Email,RSS等等)给相关的当事人。
-
配置如果存在)如果构建成功,这个构件会被打包并转移到一个部署目标(如应用服务器)或存储为软件仓库中的一个新版本。软件仓库可以是CI系统的一部分,也可以是一个外部的仓库,诸如一个文件服务器或者像Java.net、SourceForge之类的网站。
-
CI系统通常会根据请求发起相应的操作,诸如即时构建、生成报告,或者检索一些构建好的构件。
“You build it, you run it”,这是 Amazon 一年可以完成 5000 万次部署,平均每个工程师每天部署超过 50 次的核心秘籍。
解决的问题
-
高效率
高效率的发布,避免了重复性的劳动;
更快的修复BUG,更快的交付成果,减少了等待时间。
-
高质量
只有在完成集成测试、系统测试后,才能得到可用的软件,整个过程中只有最后时刻才能拿到可运行软件。集成活动不一定在一个标准的构建机器上生成,而是在某个开发人员的机器上构建的,那么可能存在在其他机器上无法运行的问题。
人与机器的一个最大的区别是,在重复性动作上,人容易犯错,而机器犯错的几率几乎为零。所以,当我们搭建完成集成服务器后,以后的事就交给集成服务器来打理吧。
-
高产出
快速开发和上市一个新产品,并快速取得预期的投资回报是每个企业孜孜以求的目标。
便捷的部署+项目的可预期,使得团队的开发变成了一种开心的事情。
持续集成可以让你在任何时间发布可以部署的软件。在外界看来,这是持续集成最明显的好处,对客户来说,可以部署的软件产品是最实际的资产。利用持续集成,你可以经常对源代码进行一些小改动,并将这些改动和其他代码进行集成。
常见问题
-
思维转变后,新技术抵触
- 无法接受新事物:不管怎么样,求稳心态的人还是多。总是有人认为老的技术代表稳定,新的事物往往会带来问题。
- 认为手工集成也没有多少工作量:不是所有的人都参与到了整个持续集成的环节,所以没有办法认识到问题全貌。
针对这个问题,可以通过设置一定的持续集成技术培训、宣讲得到改观
-
管理层的抵触
- 培训持续集成需要投入资金啊,没钱。
- 持续集成服务器要增加软硬件成本啊,没钱。
- 开发人员领了那么高的工资,多干活多加班应该啊。
针对这一点,可以从开发人员的成本和持续集成的投入(软硬件)的成本上两者做下估算。
硬件参考:
Jenkins主服务器一般2C4G,slave服务器根据生产需要进行选购。
git服务器一般2C4G(10人团队)
Docker服务器8C32G(Rancher + harbor)
-
生产环境的复杂
- 比如部署的生成环境是在政务外网,无法从互联网直接访问等。
- 构建效率低下,任务多
目前,这个是最麻烦的,还在研究中。初步设想是让政务外网开辟一个白名单,给持续集成服务器设置一个单独的通道。只是思路,未验证。
最佳实践
实施持续集成的开发人员可以尽早并经常提交。这允许他们尽早发现冲突。并且,如果存在任何问题,则使用较小的提交可以更轻松地对代码进行故障排除。每天或甚至更频繁地提交软件对于持续集成是必要的,但还不够。
要成功使用持续集成,团队必须:
-
使测试成为开发过程中不可或缺的一部分。应该在创建代码时编写测试。
公司成功持续整合所需的最重要因素是严格的测试文化。为了将新代码自信地集成到主线中,团队需要确信代码是健全的。这是通过测试来实现的,这应该定期进行。工程师应该在开发每个功能时编写测试。
-
确保测试环境反映生产一致。
为了支持您严格的测试文化,测试环境必须反映生产环境。否则,您无法保证您正在测试的内容将在生产中起作用。这意味着测试环境应使用相同版本的数据库,Web服务器配置,工件等。
-
使用编码最佳实践,例如结对编程。
软件开发的另一个最佳实践是在编码期间进行配对。对于更复杂的功能,团队在编写单行代码之前讨论体系结构方法。在将任何代码合并到生产环境之前,其他开发人员始终会检查代码。这有助于确保使用编码最佳实践,代码不会与其他开发人员正在处理的现有代码或代码冲突,并且新功能是可扩展的。
Pair programming is an agile software development technique in which two programmers work together at one workstation. One, the driver, writes code while the other, the observer or navigator,[1] reviews each line of code as it is typed in. The two programmers switch roles frequently.
While reviewing, the observer also considers the “strategic” direction of the work, coming up with ideas for improvements and likely future problems to address. This is intended to free the driver to focus all of their attention on the “tactical” aspects of completing the current task, using the observer as a safety net and guide.
-
自动化部署工作流程。
最后,为确保整个软件开发流程快速高效,构建需要快速,部署工作流程应自动化。代码构建的每一分钟都浪费了一分钟。通过自动化部署工作流程,团队可以更快地将完成的代码生成。因为,毕竟,如果没有接触到客户,那么快速开发软件有什么意义呢?
the current task, using the observer as a safety net and guide.
-
自动化部署工作流程。
最后,为确保整个软件开发流程快速高效,构建需要快速,部署工作流程应自动化。代码构建的每一分钟都浪费了一分钟。通过自动化部署工作流程,团队可以更快地将完成的代码生成。因为,毕竟,如果没有接触到客户,那么快速开发软件有什么意义呢?