💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] > 交付管道的建立和自动化是持续交付的基础 ## 持续集成 更关注代码质量。持续集成是为了确保随着需求变化而变化的代码,在实现功能的同时,质量不受影响。因此,在每一次构建后会运行单元测试,保证代码级的质量。单元测试会针对每一个特定的输入去判断和观察输出的结果,而单元测试的粒度则用来平衡持续集成的质量和速度。 持续集成的核心价值在于[1](http://growth.phodal.com/#fn1): 1. 持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量; 2. 持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之,任何时间点都能第一时间发现软件的集成问题,使任意时间发布可部署的软件成为了可能; 3. 持续集成还能利于软件本身的发展趋势,这点在需求不明确或是频繁性变更的情景中尤其重要,持续集成的质量能帮助团队进行有效决策,同时建立团队对开发产品的信心。 ### 持续集成系统 在前面的内容里,我们已经介绍了持续集成的各项基础设施——如使用版本管理、编写测试、自动化部署。要构建这样的一个持续集成系统需要下面的内容: * 支持自动构建 * 源码服务器 * 持续集成服务器 我们已经实现了前两点,针对于第三点——持续集成服务器,我们可以以 Jenkins 为例做一些简单的说明。它是一种基于 Java 开发的持续集成工具,并提供了用于监控持续重复工作的软件平台。 它可以让整个开发流程到部署都实现自动化。由于每个功能可以一点点的加在 build 中,那么这样就能保证每次的新 build 可以交付新的功能。同时,我们可以根据用户的反馈情况及时调整开发方向,降低项目风险。 ### 持续集成流程 我们就可以对这个工作流展开进入介绍。持续集成重要就是要保证整个过程是**可持续**的。如下图是一个持续集成的工作流: ![](https://box.kancloud.cn/2016-05-16_57398db6971dd.jpg) CI Workflow 不同的开发者在自己的机器上开发功能代码。在完成一定的本地提交后,这些代码将会提交给源代码控制服务器。不过,在那之前我们应该在本地跑测试来减少持续集成失败的情况。接着,我们的CI会定时去获取源码服务器是否有代码修改。如果有代码修改,那么我们的集成服务器将会获取这些代码。然后,构建这个项目,运行测试,再输出返回结果。最后,我们可以开发一些小工具来提醒用户 CI 是否运行成功。 如果这个过程中,我们我们的 CI 运行失败的话,那么我们就不能再提交新的代码——除了修复 CI 的代码外。持续集成变红不能过夜,要么快速解决,要么回退。 在这个过程中,有两点值得注意,一个是小步前进,一个是迟早反馈。 #### 小步前进 小步前进是一系列步骤的集合,其目的是:集成越早问题越小。即当我们的代码越早的提交到源码服务器,那么其他人就可以尽可能早的和我们的代码集成到一起。这也意味着,每天结束时,我们在本地的修改要尽可能小,并且这些修改还要保证不会破坏持续集成。 我们需要频繁地在本地提交我们的代码,编写独立的测试——如果我们在最后才编写测试,这会拖慢整个流程,它使得我们不能尽可能早的提交代码。 #### 尽早反馈 > 反馈越早,那么问题越小。 无论是精益还是敏捷都在强调一点——尽早反馈,反馈对于提高敏捷开发流程效力非常重要。从日常的: * Code Review * 静态代码分析 * 自动集成测试 * 自动验收测试 * 高频率发布 我们都在做尽可能小的反馈,这些实践对于我们完成一个好的持续集成来说是非常重要的基础。 参考资料: -《持续交付:发布可靠软件的系统方法》 ## 持续交付 持续交付依赖于一系列的工具和实践,下图是一个持续交付的工作流: ![](https://box.kancloud.cn/2016-05-16_57398db6b2a6d.jpg) CD Workflow 还有一系列与开发无关的技能: 1. 自动化 2. DevOps 3. 云基础设施 4. 以软件为中心的哲学 ### 基础设施 在我们使我们的项目可以持续交付软件包的时候,我们需要 #### 本地开发环境 在本地编写代码时,我们需要设置本地的开发环境。假设我们要开始一个 Java Web 项目,在我们的开发机器上,我们需要安装: * 版本管理工具,如 git,用于管理源代码。 * IDE,如Intellij IDEA,用于搭建开发环境。 * 构建工具,如 gradle,用于安装依赖、运行测试、构建工程等等。 * 语法检测工具,如 checkstyle,用于检查代码语法。 * 单元测试框架,如 JUnit,用于进行单元测试。 * 集成测试框架,如 Cucumber、Selenium,用于做行为测试。 除此,在我们的项目代码里,我们还需要: * `CI运行脚本`,用于在 CI 上运行指定的测试。 * `上传包脚本`,用于上传 build 完的软件包。 * `部署脚本`,用于在本地部署包到测试环境。 * `监控代码`,用于监测网站性能和用户行为。 当然我们还需要辅助一些测试工具来测试网站,如性能测试、网络测试等等。 #### 持续集成环境 为什么在这里会出现一个持续集成环境?我也不知道,只是想到了这里。由于我们需要持续集成,所以我们也需要一个运行持续集成服务器的机器。 持续集成服务器是由两部分组成的:Master 和 Agent。即一个用于控制其他运行持续集成服务的机器,以及执行指令的机器。因此,我们需要在一台机器上安装 Master 软件,在另外一台机器上作为 Agent。在我们的 Agent上,我们需要安装相对应的运行服务的软件,如 * 指定版本的语言环境 ,如Java、Python。 * 构建工具。 * 版本管理工具,及对应的密钥。 * 打包工具,如 RPM。 * 虚拟桌面,即可以模拟桌面浏览器的软件。 同时,我们还需要有一个地方放置我们的RPM包。 #### 测试环境 相比于上面两个环境来说,测试环境就比较简单了。我们只需要创建几个不同的环境,即开发者的测试环境、QA 环境、模拟线上环境,在这几个不同的环境上有不同的配置。 ### 持续部署 在持续交付之外的,还有持续部署——这个就更依赖于团队的组织结构了。其与持续交付的对比如下图所示: ![](https://box.kancloud.cn/2016-05-16_57398db6d6e87.jpg) 持续部署 我们可以从图中看到,两者的最大不同之处在于:持续部署会直接将构建生成的部署到产品环境。这就意味着,我们不仅要有强大的技术实力,也要有足够的组织支持才能做到。而这部分已经超出了软件开发的内容了~~。 ## 持续学习 如果说`持续交付则是一种对卓越的追求`,那么`持续学习应该就是追求软件卓越`。 如果说`持续集成是一种软件开发实践`,那么对于技术人员来说——`持续写作应该就是持续学习的实践` 生活总会遇到压力,来自工作上的也好,来自对于技术上的兴趣也罢,我们需要持续来断地学习。没有一直能立于不败的方法,在传说中的武林上也是如此。 对于持续学习来说,通常会有以下的 * 阅读 * 编程 * 写作 有意思的是持续学习有额外的好处便是 * 持续学习可以降低危机感 ### 持续阅读 看过如此多的金庸、古龙小说我们都会发现有那么多的人都在追求武功上的卓越,有的走火入魔了,有的铤而走险杀人放火,暂且不讨论这些。我们简单的以大部分的主角为例,大部分的主角自小就练得一手好武艺,少部分除外,而他们通过会比前辈厉害,只是因为我们看了前人的说,现在也是如此。 **20 年前要建一个淘宝怕是没有两三个月十几个是不行的,但是今天要建出原来淘宝的模样,也许一个人单枪匹马一两天就能搞定了,还能上线。** 有意思的是武林小说的武林秘籍少之又少,正常情况下能学到的或许就是教科书上的种种。而现在,如果我们要学习 `UX` 的话,我们很容易可以从亚马逊上拿到一个书单,又或者是某个博客里面列举出来的:《用户体验要素》、《交互设计沉思录》、《怦然心动——情感化交互设计指南》等等。 我们可以更加方便快捷地获取我们所需要的知识从书上、网上等等。 `阅读更多的书籍是持续学习的基础。` 总会听到有些人在工作之余看了更多的书,在某种情况下来说是有意义的。我们需要不断地去阅读。 ### 持续编程 编程算是一个开发人员工作时一直在做的,而对于工作之后来说,到底还会有多少人继续编程就是一个有意思的问题。 对于一个有兴趣的程序员来说,工作和兴趣都是分开的,可以将工作视之为无味的东西,但是休息时间呢?可以用来创造自己觉得有意义的东西,可以用来认识更多志同道合的人,对于不满现状的人更是如此,或许为自己创造了更多的机会。 如果工作之后编程,不应该是为了工作而编程,应该为了兴趣而编程,或者其他。如果没有时间,是不是因为加班了,对于刚开始养家糊口来说加班是没有办法的,但是如果不是的话,又没时间,是不是…… ### 持续写作 对于一个技能人员来说,写作可能不是一件有意思的事,但是也不是一件很难的事,没有必要将大量的文字用文本表示。写给其他技术人员看的,有时候更多的是代码、思路、图。写作对于学习的意思怕是有一大把,写作是最好的输入,也是最好的输出。你需要为你的这篇文章 * 去参考更多的资料 * 更深入的学习 * 更多的时间付出 然而这些都是有价值的,你也许可以从中得到 * 一份工作 * 一些志同道合的朋友 * 一个博客 * 一种习惯 * 还有人生 * 或许还能写书。 对于我来说,更多的是对于`读者`和 `SEO` 的兴趣,SEO 是一门艺术。