写点什么

互联网行业持续交付的经验

  • 2012-12-19
  • 本文字数:3544 字

    阅读完需:约 12 分钟

持续交付概念的流行反映了业务部门对于更快交付速度的渴望和技术团队对交付这一老大难问题的重视。从持续集成到持续交付,ThoughtWorks 一直在积极的实践、思考、总结。这篇文章中我将分享 ThoughtWorks 一支开发团队在这个领域的收获和总结。

背景

我们的客户是澳洲的房地产搜索门户,每年独立访问者近 300 万 (澳洲人口 2000 万),年营收近 3 亿美金,澳洲 61%的房产都在此网站展示。我们的团队工作在商业地产、住宅、土地购置等与盈利息息相关的全产品线的核心系统上。

成就

2 年前,与大多数“常规”项目一样,部署和发布是一件费时费力、加班加点的活动。作为一家历史超过 10 年的互联网公司,已经有大量复杂的业务系统支持着线上业务的正常运转,部署和发布任何一个功能都是牵一发而动全身的复杂活动。对我们的客户来说快起来不是一件容易的事情,但它不得不快,因为竞争对手在频繁的进行商业活动,不快速的求变、求新它将难以保持领先的市场地位。持续交付以及持续交付所支撑的持续创新能力是它必须建设的核心竞争力。

对于 ThoughtWorks,持续交付是增加项目进度的可见性,降低项目“最后一公里”风险的重要工具。这样,投资建设持续交付能力成了合作双方一拍即合的决定。经过了两年的摸索与实践,总接下来, 收获主要有以下四点:

一键部署:目前的部署流水线从提交开始,到自动运行各种验证,再到最终的安装、配置软件可以做到全程无须人员干预,最终的部署过程可以在几分钟内自动完成。具备了快速部署,持续部署的能力,一天多次部署,一周多次发布就成了顺利成章的事情。

由离岸团队执行部署和发布:中国团队的成员大多是开发人员,对产品环境了解不足;分布式环境让中国的团队没有太多的机会从澳洲团队身上学习如何部署和发布,这样的内忧外困下,得出“由离岸团队来执行部署和发布风险太高”这个结论似乎是很自然的,然而随着持续部署过程越来越熟练和成熟,我们发现上面的结论是与部署手段原始落后的现状息息相关的,一旦发布手段变的高明,由离岸团队部署和发布的风险是完全可以接受的。

业务人员变得更加敏捷:随着部署肌肉的越来越发达,业务人员开始习惯了这样一种对话方式,“唔,这个功能很不错,我们发布出去看看用户是什么反映吧?”,和以往仔细计划、严格执行的风格相比,业务人员的决策过程变成了:

  1. 尝试某功能
  2. 通过对响应数据的分析,理解功能的市场反应
  3. 决定继续开发还是改变方向,不断循环和迭代

通过功能频繁上线,业务人员的思路和做事风格也变的更加敏捷。

业务团队与技术团队理解了部署和发布软件是两个不同概念、两件独立的活动:2 年前,项目部署和发布的时间点从来都是高度统一的,部署结束发布就结束。团队一直没有意识到软件的部署和发布是不同的概念和活动。事实上软件部署是技术概念,包括了:

  • 创建和管理应用所依赖的硬件软件环境
  • 把正确的软件安装到上述环境中
  • 正确的配置产品,使其按照预想的方式运行

软件发布则是业务概念,它包括了决定:

  • 哪些业务功能应该让用户使用?
  • 在什么时间让用户使用?
  • 让哪些用户使用?
  • 必要的市场推广,客户、支持团队培训是否就绪?

通过技术改造,大家明确了部署是一周进行多次,甚至一天进行多次的技术活动,而发布则严格与业务目标对齐,通常以几周为频率。

最佳实践

团队所取得的成就来自于对方法、工具和流程的摸索和应用,我们认为有三个实践对于实施持续交付是至关重要的:

功能开关 (Feature Toggle):持续交付不仅仅意味着使用新工具、新方法。它还意味着从设计和编码阶段就需要作出改变,功能开关是其中一项重要的设计实践,它的目的是方便的打开和关闭某个特性。为什么需要功能开关? 因为在持续交付的过程中,团队会遇到下面的情况:

  • 功能没有就绪,还不能让用户使用
  • 功能就绪,但是相关的业务活动(培训,市场活动等)没有就绪,不能让用户使用
  • 业务人员要求功能只开放给部分用户
  • 测试不充分导致的产品缺陷需要关闭功能

功能开关可以用于解决上述问题。它的具体实现多种多样,我们在不同的场景中使用过:

  • 灰度上线:功能部署上线但是把用户可见的操作都屏蔽掉
  • 文件配置:通过配置文件决定某个功能是否对用户可见或关闭
  • 状态数据:通过数据库中的状态值决定某个功能是否对特定用户可见或关闭
  • 编译参数:再编译过程中通过编译参数决定某些特性打开或者关闭

自动化 (Automation):要想频繁的部署、发布而且每次部署都不能出错,是难以离开自动化过程的,我们团队的自动化部署流水线是这样设计的:

  1. 本地测试通过后,开发人员提交代码。
  2. 触发 package: 执行静态检查,单元测试和功能测试,并生成编号的二进制包供后面的阶段进一步测试。
  3. 触发 acceptance_standalone:在 EC2 上搭建出单机产品环境,运行集成测试。
  4. 触发 acceptance_staging:在 EC2 上搭建出最小集群环境,运行另外一些集成测试。
  5. 触发 publish:将 package 阶段生成的二进制包发布到公司内部的软件仓库中
  6. 利用命令,测试人员可以自动化地取出第二步所生成的二进制包,并自动搭建出产品环境进行手工测试。
  7. 手工触发 deploy:相关发布包被安装在产品环境上,完成部署。

我们使用了很多软件来支持上面的自动化部署过程,比如 :

  • Buildr: 用于编写自动化构建脚本
  • JUnit:用于编写与运行自动化单元测试
  • Cucumber:用于编写与运行自动化验收测试
  • Amazon EC2: 用于创建和管理测试环境的虚拟服务器
  • VMware vSphere: 用于创建和管理产品环境的虚拟服务器
  • Chef:用于基础设施 (操作系统,应用服务器) 的搭建和配置
  • Go: 用于设计和实现部署流水线

虚拟化:虚拟化提供了充分测试所需的平台。能够高度自动化的测试和发布并不意味着高质量的部署和发布。在测试过程中能不能发现问题是非常关键的。不难理解,测试环境和产品环境越相近越容易发现问题,但产品环境通常复杂而昂贵,传统方式根本无法有效的向每个开发人员提供一套环境用于测试,而虚拟化则可以做到这一点。

我们目前在 EC2 上搭建出了 300 多套环境供 300 多澳洲和中国开发人对软件进行充分的测试,它的优势有:

  • 容易复制,并且可以根据需求弹性的增加。
  • 容易同步,产品环境的变化可以通过脚本自动的同步到测试环境,减少差异。
  • 容易自动化,有大量的开源软件支持

教训

当然在实施持续交付的过程中,我们也犯过很多错误、走了一些弯路,比如:

没有设计防呆机制,开过自动档汽车的人都知道,不踩下刹车无法挂前进档,这就是一种防呆机制。一个高度自动化的部署过程也需要设计防呆机制,防止出现重大错误。我们曾经因为错误的修改了脚本,高度自动化的流水线很快将测试数据刷入了产品环境,结果巴掌大一块空白出现在百万级访问量的产品首页正中间,没有防呆机制的高度自动化环境很带给团队的可能是更快的部署过程,也可能是更多的线上严重错误。

没有精确复制产品环境:我们的产品曾经通过部署流水线的验证并成功上线,然后很快客户发现产品的背景和布局出现了明显的错误。紧急排查后发现错误来自于一段排序算法,这个算法在测试环境使用的 ree-1.8.7 中没有问题,但在产品环境的 ruby-1.8.7 会出现异常。它教会我们不能想当然,产品环境和测试环境的任何一个差异点都可能是潜在的问题点。

脆弱的部署流水线带来的高维护成本:环境越接近真实,测试就越复杂脆弱,相应的维护成本也越高。自动化程度最高的团队目前有 50% - 70% 的构建失败是由环境问题引起的,比如:搜索引擎不稳定,会出现清理和更新数据失败的问题、从第三方获取的广告不稳定导致导致超时失败等。这些失败带来的直接成本是修复构建的时间,间接成本是团队需要花时间设计更高明、更稳定测试的精力和时间。这些成本是任何一个需要实施持续交付的团队都得做好心理准备的。

未完成的实践

我们目前还无法基于真实数据设计整个测试、迁移、部署、发布的过程,使用真实数据对于稳定、高质量的验证、部署过程至关重要,但有些棘手的问题让我们无法采用真实数据,比如:

  • 数据库很“大”:10 多年积累下来的数据以 T 记,要想测试必须对数据进行裁剪,如何有效裁剪?因为裁剪不当,我们多次发现因为数据引发的线上问题。
  • 数据库很“敏感”:相对于产品环境,产品数据更加敏感,它往往是一个公司的核心竞争力,各种安全策略保证无法每人都有可以使用这些数据。
  • 数据变化难以“自动化”:开发团队和数据库团队使用不同的工具,对于变化的态度也非常不同,结果是开发团队成熟运用的工具和实践并不能使用到产品环境的数据迁移中,整个审查、验证、应用变化的周期依然漫长,拖慢了产品发布的速度和节奏。

对于其它方面,我们已经有了一套成熟的理论和实践,但对于数据库层面我们还在摸索,也希望看到和听到这方面更多的意见和建议。


感谢张凯峰对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2012-12-19 07:468361

评论

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

OPPO 小布预训练大模型揭秘:可大规模工业化应用的十亿级模型

OPPO小布助手

AI 智能助手 预训练模型 预训练

LeetCode-168. Excel表列名称(java)

bug菌

LeetCode 7月月更

激进技术派 vs 项目保守派的微服务架构之争

BoCloud博云

微服务 微服务架构 云原生 istio 服务网格

uni-app与uviewUI实现仿小米商城app(附源码)

优秀的李

小程序 uniapp 7月月更 uviewui

Nebula Importer 数据导入实践

NebulaGraph

图数据库 数据导入 Nebula Graph

能源行业的数字化“新”运维

博睿数据

AIOPS 智能运维 博睿数据 能源行业

太方便了,钉钉上就可完成代码发布审批啦!

阿里云云效

云计算 阿里云 钉钉 jenkins 代码

DataKit——真正的统一可观测性 Agent

观测云

【Unity UGUI】ScrollRect 动态缩放格子大小,自动定位到中间的格子

萧然🐳

游戏开发 Unity ScrollView 7月月更 UGUI

什么是低代码开发?

AIRIOT

低代码 物联网 低代码,项目开发

五千字讲清楚团队自组织建设 | Liga 妙谈

LigaAI

团队管理 个人提升 敏捷开发管理 LigaAI 自组织协作

Numpy 的仿制 2

祖维

c slice Numpy

Python 入门指南之使用 Python 解释器

海拥(haiyong.site)

7月月更

字节跳动Dev Better技术沙龙成功举办,携手华泰分享Web研发效能提升经验

字节跳动终端技术

字节跳动 前端

第十八届IET交直流输电国际会议(ACDC2022)于线上成功举办

E科讯

图像检索(image retrieval)

Geek_e369a5

图像搜索 图像检索

NBA赛事直播超清画质背后:阿里云视频云「窄带高清2.0」技术深度解读

阿里云CloudImagine

音视频 直播 视频编码

TCP两次挥手,你见过吗?那四次握手呢?

C++后台开发

网络编程 网络协议 TCP/IP 后端开发 C++开发

被忽视的问题:测试环境配置管理

老张

软件测试 测试环境治理

LeaRun.Java快速开发平台 高效代码自动化生成

力软低代码开发平台

一加10 Pro和iPhone 13怎么选?

Geek_8a195c

智捷云——元宇宙综合解决方案服务商

智捷云

区块链 元宇宙 智捷云 区块链技术开发

你可能不知道,我是如何将一个老系统的kafka消费者服务的性能提升近百倍的

Java全栈架构师

Java kafka 程序员 面试 架构设计

华为云ModelArts的使用教程(附详细图解)

逝缘~

华为 华为云 7月月更

同事悄悄告诉我,飞书通知还能这样玩

Jianmu

自动化 建木CI 飞书通知 定时

DeFi生态NFT流动性挖矿系统开发搭建

薇電13242772558

NFT DeFi流动性挖矿

英特尔集成光电研究最新进展推动共封装光学和光互连技术进步

科技之家

linux实战清理挖矿病毒kthreaddi

入门小站

Linux

PingCode 性能测试之负载测试实践

PingCode研发中心

软件测试 PingCode

输入的查询SQL语句,是如何执行的?

华为云开发者联盟

MySQL sql 开发 语句

整理混乱的头文件,我用include what you use

华为云开发者联盟

c++ 开发 C语言 技能

互联网行业持续交付的经验_研发效能_胡凯_InfoQ精选文章