写点什么

持续集成之“Everything is code”

  • 2012-01-06
  • 本文字数:3109 字

    阅读完需:约 10 分钟

前文《软件自我识别》中,我们讨论了如果使软件做到自我识别,以促进自动化部署和版本检测等工作。 随着互联网的飞速发展,以及基础设施的改进,越来越多的业务被放在了“云”端。管理数千台服务器和各种应用程序的不同版本已经是一种常规事务了。那么如果管理好这些机器和代码吗?本文将介绍一些最佳实践,来帮助大家更好的完成相关的事务。

一、测试代码不是二等公民

业务压力让团队人力显得有点儿紧张。一天下午,大家在紧张的工作着,新的版本即将发布了。突然,有两个同事的对话引起了Joe 的注意。

“Hi,Sam。过来看一下,我这里有个自动化测试失败了。”刚刚加入团队的测试人员Jared 叫了Sam 一声。

“咦?我本地没有这个测试,可我更新过我本地的代码了呀?”Sam 一脸茫然地应到。

“哦,是吗?不会吧。我也是刚刚从SVN 上更新了代码。”Jared 说道。

“Jared,你再更新一下,也许是你在我提交之前更新的呢。。。哦,还是一样的结果。那到我的工作站上看一下吧。”

“噢,原来你把测试放在了这里。”Sam 恍然大悟的样子,“我们两个人使用的测试套件版本是不一样的。根据用户的反馈,我们重新修改了产品的一个小功能,所以,这部分功能的原有自动化验收测试逻辑就不对了。”。SVN 代码仓库的目录结构如图1 所示。

图1 产品代码与测试代码分离

这时,Joe 也凑了过来。“嗯。我们应该修改一下我们的代码在SVN 中的组织结构。把测试代码和产品代码放在同一个代码库中,做到产品代码与测试代码同源。”

Jared 问道:“为什么要这么做呢?我在上一家公司的时候,测试团队也是把功能测试用例放在公司自行开发的一个测试用例管理平台上进行管理。当需要做老版本的回归测试(比如 V1.0)时,我们只要在这个平台上勾选上该版本对应的测试用例,再点击‘执行’按钮,就可以了。当有新版本, 比如 V1.1 时,只要把 V1.0 的所有测试用例复制一份,标记为 V1.1,并在其上修改就可以了。测试代码的组织方式常常是使用目录结构来分离版本。”如图 2 所示。

图 2 以目录方式对测试用例进行管理

Joe 回答到:“你刚才所说的做法,我也在其它公司见过。这种做法常见于使用传统瀑布开发模式的团队,即开发阶段与测试阶段分离。在开发阶段,大家并不会频繁运行相应的自动化测试,这些自动化测试是为测试人员服务。而在我们这里,自动化测试是为所有人服务的,开发人员随时都会运行测试。其实,我们大部分的测试都已经与产品代码放在了同一个代码仓库中了。只是这一部分是比较老的代码,需求也一直没有变化,自动化测试也一直运行成功,所以就没什么动力去迁移这部分测试代码。”

Joe 停顿了一下,喝了一口咖啡,接着说道:“当我们做到产品代码和测试代码同源时,我们只需要从一个 svn 代码仓库中签出某个版本的源文件,就同时得到到产品代码,以及与该版本相对应的测试代码。所以,不会出现版本不一致,或者需要手工挑选测试用例的问题。现在服务器很多,应用程序使用灰度放量发布的方式,在生产环境中可能会有多个版本。假如正在运行的某个版本出现了问题,需要修复,那么,我们很容易就能拿到与其对应的所有代码。因此,不能把测试代码作为代码中的二等公民,而是应该得到与产品代码同样的重视。我们代码库中的目录结构是这样的。”如图3 所示。

图3 测试代码与产品代码同源

二、配置信息也是代码

Alex 此时也凑了过来,接道:“不只是对代码需要一视同仁,配置信息也一样要放到代码仓库中。这方面,我们也是有着痛苦经历的。记得是几个月前,那时候我们的产品还不大,为了快速调整,我们经常在生产环境中直接修改配置信息,如数据库连接,功能开关项或者 IP 地址什么的。结果,每次准备上线前的测试时,都要到生产环境上去下载一份配置信息。有一次,生产环境上的一台机器出了问题,结果那台机器上的所有信息都丢了,害得我们到处找,花了很长时间才把那台机器重新配置好。现在都放在代码仓库中,就可靠多了。”

“配置信息是指哪些呢?”Jared 问道。

Joe 回答道:“配置信息包括应用程序相关的配置,以及程序部署时的相关配置。应用程序相关的配置是指影响应用程序行为的配置项,比如某个功能的开关、数据库连接、缓存的大小等等。程序部署时的相关配置是指部署在不同机器上的程序组件是如何相互连接的,如 IP 地址等等。”

“那有些配置信息是动态生成的,那怎么把它放到 SVN 中呢?”Jared 接着问道。

“我们首先要把动态信息与静态信息分开。一般对于动态信息来说,只要把其变动的规则保存在 SVN 中就可以了。”Alex 答道。“比如,某些 IP 地址或内部域名是自动配置的,那么就把自动配置的脚本放到 SVN 中就行了。这样,一旦出了问题,我们也可以确切地知道,所用的分配规则是什么样的。”

“那生产环境的配置与测试环境的配置不同,与开发环境的配置也不同,怎么办呢?”Jared 穷追不舍。

“这个好办,只要存三份配置,对应三种不同的环境就可以了。”Joe 笑道,“所以,我们代码目录结构是这样的。”他拿起笔,在纸上画了一下,如图 4 所示。

图 4 以业务为核心组织产品结构

三、脚本文件也是源代码

“嗨,Joe。这里的 script 目录里面放什么的呢?”Jared 问道。

“哦,这个目录是放所有我们用到的脚本的。”Alex 笑着说,“以前大家在测试、部署等工作中写了很多脚本,用在各自的工作中。现在我们统一放在这个目录中,这样所有人都可以使用相同的脚本做相同的事情。比如,当开发人员在自己调试时,只要执行部署脚本 autodeploy,它就会从开发配置目录 (conf/dev) 中读取相关配置,部署好开发调试环境。而测试人员使用同一个部署脚本 autodeploy,它就会从测试配置目录(conf/test)目录中读取相关配置,部署好测试环境,生产环境部署也运行同一个脚本,只不过说生产环境配置而已。”

“这样不错。我们的脚本在最终向生产环境部署之前就已经被测试过很多次啦。”Jared 笑道。

四、数据也是代码吗?

“我们有点跑题了,回到我们最开始遇到的那个测试问题上吧。”Jared 说,“那个测试失败,除了功能的小改动以外,log 里还有一些异常,好象是数据格式问题。”

“嗯,这部分测试用到的数据放在一个固定的共享目录中了。可是,虽然文件名没有变化,但其中的数据格式已经改了。也就是说,这份测试代码与测试数据存在不一致性。”Joe 说道。

Alex 接道,“嗯,我们现在把数据也放到了代码仓库中。”

Jared 一脸狐疑,问道:“数据那么大,怎么放到代码仓库中呢?SVN 保存大数据并不高效,而且占用空间也比较大呀。”

“Alex 只说了完了一半。其实,我们是把大数据放在了一个我们自行开发的版本控制系统中了。当把一份大数据放在其上时,该系统会返回唯一的一个标识 ID,我们把它放在了这个产品代码的 conf 目录中。这样,当签出某个版本的代码时,你就可以直接拿到对应的大数据了。如果大数据修改了,那只要把放再次放到那个大数据存储系统中,然后把返回的唯一标识更新到对就应的 conf 目录中就行了。”Joe 补充道。“如果没有这样一个大数据库版本管理系统,也可以使用共享目录,只不过,每个子目录下保存一份数据,把这个子目录地址放在 SVN 里,也就行了。”

“对于数据库结构的修改,我们还有另外一种方法,就是利用类似于 DBmaintain 或是 DBDeploy 这样的工具。把每一次数据库结构的变更都写到一个数据库脚本,并把它们和代码放到一起。这样,升级过程就由这些工具就完成了。”

五、Everything is code

“哦,我明白了。”Jared 说道,“就是围绕我们的服务或产品,将所有的东西进行版本管理。这样,所有的内容都只有唯一的一个源,所有人都可以拿到同样的信息,而且自动化工作也非常容易了。”

“是的。而且,当完成这一步以后,所有的事情自然都成为可跟踪可追溯的了。”Joe 笑道:“这也算是一个额外的收益吧。”

2012-01-06 06:334543
用户头像

发布了 100 篇内容, 共 21.8 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

统一观测丨使用 Prometheus 监控 E-MapReduce,我们该关注哪些指标?

阿里巴巴中间件

阿里云 云原生

火山引擎DataTester:一个A/B测试,将一款游戏的核心收益提升了8%

字节跳动数据平台

大数据 游戏 AB testing实战 企业号 3 月 PK 榜

如何有效的进行用例评审

京东科技开发者

用例 京东云 代码评审 企业号 3 月 PK 榜

社交软件的月活利器:从UGC到互娱

HIFIVE音加加

互联网 软件 社交 科技 社交媒体

“一键飞桨”,轻松实现飞桨框架和套件的下载安装!

飞桨PaddlePaddle

框架 飞桨

ios系统修复软件:Fix My iPhone 激活版

真大的脸盆

ios Mac 系统修复 Mac 软件

Orika JavaBean映射工具使用

京东科技开发者

JAVA开发 京东云 JavaBean 企业号 3 月 PK 榜

如何科学管理技术团队的研发交付速率?

LigaAI

DevOps 研发效能 技术管理 效能度量 企业号 3 月 PK 榜

详解AQS的7个同步组件

华为云开发者联盟

后端 开发 华为云 华为云开发者联盟 企业号 3 月 PK 榜

早有尔闻 | 海尔智家牵头IEEE智能家居语音国际标准

Openlab_cosmoplat

工业互联网 开源社区 智慧生活

限时促销,火山引擎ByteHouse为企业带来一波数智升级福利!

字节跳动数据平台

数据仓库 云原生 促销 特惠 企业号 3 月 PK 榜

阿里云消息队列 Kafka 生态集成的实践与探索

阿里巴巴中间件

kafka 阿里云 云原生 消息队列

浅谈kafka

京东科技开发者

数据库 中间件 京东云 kafka manager 企业号 3 月 PK 榜

爆款歌曲的养成背后,是哪些因素在推动?

HIFIVE音加加

娱乐 音乐 娱乐社交 热门 华语音乐

LLaMA快速上手指南

Baihai IDP

人工智能 自然语言处理 AI ChatGPT 白海科技

全面图像编辑:ON1 Photo RAW 2023激活版

真大的脸盆

Mac 图像处理 Mac 软件 图像编辑 raw

这款 IDEA 插件太好用了,堪称日志管理神器!

程序知音

GreatSQL 8.0.25-17今日发布

GreatSQL

greatsql greatsql社区

巧用GenericObjectPool创建自定义对象池

京东科技开发者

京东云 API 编排 对象池 京东物流 企业号 3 月 PK 榜

Matlab常用图像处理命令108例(三)

timerring

图像处理

5个高并发导致数仓资源类报错分析

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

LED显示屏闪烁原因及解决办法

Dylan

LED灯闪烁 LED显示屏 全彩LED显示屏

架构师日记-软件高可用实践那些事儿

京东科技开发者

高可用 软件架构 京东云 企业号 3 月 PK 榜

从零打造你的前端开发脚手架

南城FE

前端 js 前端工程化 脚手架

对比分析数仓中行列存的特性

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

聚焦企业数据生命周期全链路 火山引擎数智平台VeDI发布《数据智能知识图谱》

字节跳动数据平台

大数据 字节跳动 云服务 数据产品 企业号 3 月 PK 榜

Amazon Global Accelerator 的新增功能 — 互联网协议版本 6(IPv6)支持

亚马逊云科技 (Amazon Web Services)

互联网 亚马逊云科技

async 与 Thread 的错误结合

newbe36524

C#

Databend query result cache 设计与实现

Databend

基于 Flink 流计算实现的股票交易实时资产应用

Apache Flink

大数据 flink 实时计算

架构实战营模块八作业

程序员小张

「架构实战营」

持续集成之“Everything is code”_Java_乔梁_InfoQ精选文章