摘要: 阿里持续交付平台已经经历了 8 年的不断迭代进化,成长为集团几万应用所依赖的最重要的研发工具,它的效率直接影响着几万研发日常工作。但平台不能只是工具的堆砌,更需要针对互联网时代的研发模式进行深度思考,不断打磨,将工程师文化和工程师实践不断地融入其中。
阿里持续交付平台已经经历了 8 年的不断迭代进化,成长为集团几万应用所依赖的最重要的研发工具,它的效率直接影响着几万研发日常工作。但平台不能只是工具的堆砌,更需要针对互联网时代的研发模式进行深度思考,不断打磨,将工程师文化和工程师实践不断地融入其中。轻管控重技术,使用业界上最新工程实践,用技术的演进去解决技术人的效率问题。本次演讲将介绍阿里持续交付工具的演化历程和对互联网行业交付领域热点问题的思考实践。
注:本文整理自阿里巴巴高级技术专家陈鑫(神秀)在 ArchSummit 全球架构师峰会 2017 深圳站上的演讲,原题为《互联网时代的持续交付》。
写在前面
大家好,我来自阿里巴巴,花名神秀,今天给大家带来的 topic 是互联网时代的持续交付。为什么在持续交付前面要强调互联网?阿里的持续交付实践有什么特别之处?希望我在这里能够抛砖引玉,给大家带来一点点收获。
我在阿里负责持续交付平台和研发工具链建设,以及将对应的能力通过阿里云输出,我们对外的版本叫云效,公有云上目前正在公测中。
首先给大家介绍下今天的几个主要内容。
首先着重介绍一下阿里这些年持续交付工具上的演进和我们的建设思路。
然后会和大家一起探讨一下互联网企业产品快速演进下的一个重要话题:质量和效率,介绍我们怎么看待这两者之间的关系,以及如何协调。
再一个是我们正在面对的问题:交付和 devops,传统软件企业对交付肯定不陌生,但对于阿里场景下我们会有一些新的挑战。Devops 方面介绍下我们最近一年的进展和一个小创新。
发展:持续交付在阿里
时间线
首先介绍下阿里持续交付平台的发展历程:第一阶段2009 年我们做了一个简单的自动化发布工具,来解决 SCM 和 PE 同学单点问题。在这之前可能很多企业都经历过这样的过程,固定时间提交发布申请,配管同学开始统一冻结代码打包,然后交给运维同学进行发布。在小团队小企业时也勉强够用。应用规模越来越大,线上环境越来越复杂时,配管和运维同学的能力和效率开始阻碍我们产品的发展。当然其中也有一些腐败,比如要搭车紧急发布要请配管同学喝咖啡什么的。开个玩笑。
没过两年,研发人员越来越多,各种复杂研发规范,线上各种复杂脚本,各种新同学挖坑,后人踩坑苦不堪言。这一切必须规范起来,后来到了 2013 年我们把从代码变更到线上发布完全统一了起来,通过统一构建部署平台进行严管控。
显然这还远远不够,到了 2016 年,平台再度升级。上线了从需求到代码,从交付到反馈的一站式平台。项目、需求、代码、构建、测试、发布、流水线、舆情反馈等等等等,产品大图基本完备。
在 2017 年,我们把这 8 年的平台工具经验开放到了阿里云,也就是云效这个产品,希望通过阿里经验反哺云上生态,同时也依托广大研发者的经验帮助我们工具成长。
工具与理念演进
说完了发展历程,下面介绍下我们的工具和理念的演进过程,下面会针对这四点详细展开。
第一是自动化,自动化是工具首先要完成的价值,也是效率提升的最直接的抓手。对于我们会先做好配置、代码、测试、运维的自动化。
第二是标准化,标准化是工具平台最大使命,比如亚马逊经常讲到的Apollo环境部署工具就做的非常棒,阿里也有自己的研发标准和运维标准,研发标准中比如研发模式、技术栈、配置管理规范相对好做。运维域就相当困难,目前 web 应用、移动应用、搜索、系统基础软件等会自成体系,集团内部和阿里云也会略有不同。但是随着容器化和统一调度的推进,这些都有望统一。
第三是定制化,定制化应该是对平台的更高要求,不同团队,不同技能水平对工具天然就有不同的需求。我们不能因为管控而丧失灵活性,也不能因为照顾低水平技能而限制高水平。因此我们会首先按照团队成熟度来推荐适合的交付过程和管理规范。
第四是一站式,当工具开始百花齐放时,对研发同学是有一定伤害的,不同的交互,不同的产品对接形态,不但会增加系统复杂度,也让效率在平台之间的流转中降低。因此我们通过平台工具融合,将需求到反馈的整条链路打通,在一个平台完成基于价值的交付。
自动化一切
好,先看下我们的第一个理念:自动化一切。这张图展示的是一个常见的研发过程,我们先从 master 拉出开发分支进行开发,合并成 release 分支进行发布,发布完成后合并到 master。应该每个研发团队都有自己的一套规范来处理分支问题。当团队规模越来越大,或者出现新人的时候,如何规范操作,提高协作效率,避免错误,那么就需要工具来承载这一切。
我们将常见的几种研发模式:主干开发、分支开发、gitflow 等从拉分支开始,到 mergerequest、代码合并、冲突解决全部白屏化解决,最终简化成一个 pipeline,一个开发新手只需在平台上操作就可以马上融入研发工作而不会出现任何差错。
标准化落地
再看关于标准化方面,工具层面主要完成了这几个方面:应用创建、测试验收、标准环境、上线卡点、部署过程。
一个应用对应一个代码库,一个服务单元,我们通过代码推荐、技术栈模板对集团标准进行落地和迭代,比如 springboot 推广。通过资源编排来快速完成基础设施的申请搭建。
测试验收方面集团规约和安全测试是这几年主推的标准,已经在全集团落地,代码质量得分则是通过数据度量的方式,客观评测当前应用质量情况。
标准环境是交付流水线和运维管控的基础,通过容器化和统一调度现在可以比较容易的实现,第四点比较有意思。原来的工具思路往往是出现部署、资源问题,会引导用户通过自动化工具自助解决,比如清理日志、重启机器等。现在我们会更多的采用自愈的方式,把环境资源运维工作下沉到平台无人干预式解决,用工具替代人。
上线卡点多是一些管控类需求,基于集团统一的管控策略来定,控制研发行为和质量。
最后部署过程,发布策略、监控、基线、回滚都是必备功能,我这里就不再赘述了。
定制化解决方案
要实现定制化,先看下解决方案的几个因素:
团队成熟度:规模如何,1-2 人,7 人,10 人以上?全栈还是有独立测试运维团队?质量如何,是否有技术债务?团队内部有什么特别的规范约定?
迭代速度:每日随时发?还是周期性交付?是否有窗口限制,从我们持续交付的角度,我们并不想对上线行为做过多约束,符合卡点应该即可上线,阿里现在核心应用基本都做到随时发布,甚至一日多次发布。
BU 技术栈:各自 BU 的一些私货规范,和个性化差异。虽然我们一直在建设统一基础设施和研发运维平台,仍然无法做到 100% 统一,是我们一直努力的方向
最后是集成交付:是否有产品集成需求,项目交付?或者专有云交付。比较典型的就是电商、移动端、阿里云三种形态。
由这四点因素我们推导出了几种定制化方向:
研发模式:根据应用小规模团队采用分支研发,共建型大团队采用 gitflow,更加庞大的团队采用主干开发模式。因为微服务设计的流行,现在应用的团队规模越来越小,所以在阿里分支研发模式会更受欢迎。
技术栈:java、C++、脚本类等等,我们会采用代码推荐和模板化的方式,帮助用户一键创建代码框架和编译环境。
部署模板:常见的做法是软件包模板和 Dockerfile。在阿里,很多 BU 架构负责人和 PE 都会提供各种技术栈基础镜像,帮助普通研发者快速部署环境,类似这种的技术栈管控也同样依靠工具来承载。
最后依靠多级 pipeline 来实现多种类型的交付过程,来满足集成交付需求。
一站式平台
大家现在看到的是目前阿里云效研发协同平台的全貌,总体可以分为项目协作和持续交付两大部分,交付部分形成了从需求到反馈的完整闭环,其中反馈部分不单单只有效能度量,还有针对业务本身的舆情分析和问卷调查,以及智能化客服工具。
工程师文化落地平台
最后说一下我们建立平台工具的最终目的,就是将工程师文化落地平台。当然工程师文化是一个很虚的东西,每个企业都有自己的文化。包括阿里自己内部淘系、B2B、阿里云等 BU 都有各自特点。不过总结下来会有以下四点:
质量文化:质量是持续交付的核心所在,团队成长的必经之路。没有质量的文化传承,效率无从谈起,代码会很快腐烂,无人敢动,成为技术债务。更不要说快速迭代和持续交付了。
创新文化:作为研发中台的我们,不可能也不必要成为所有工具创新、效率创新的来源。在阿里本身也有浓厚的创新文化,今天我们碰撞出一个 idea,明天就有一帮哥们把他变为一个工具或者小产品。创新被人发现后还会快速的发展成一系列生态。这些事情每天都在发生,对于我们工具平台来说,应该成为一个载体,将最优秀的创新落地在平台之上,促进相似产品的融合避免重复造轮子,也可以推广引流,做强做大,形成正向循环。
全栈文化:现在都在讲 devops,但没有工具承载的 devops 基本上是空谈,当我们平台可以帮助 dev 自动完成 ops 工作,或者引导促进知识学习时,才能做到研发、测试、运维协作的无死角。
精益文化:这个才是我们一站式平台的理念所在:基于价值的交付,基于数据的准确度量,帮助开发或者领导者评估产品价值和优化团队效率。
好,以上就是我们对阿里内部研发工具建设上的一些实践,希望能够抛砖引玉,共同探讨。
两大挑战:质量和效率
接下来我们探讨一个话题,质量与效率,这可能是工程领域一个永恒的话题,我们今天就聚焦在互联网场景下,我们的软件怎么来解决既要又要还要的问题。
先看下在互联网时代我们的一些挑战:
当交付速度决定市场:我们 CTO 曾说过,研发工具要保障一个 idea 从诞生到上线在 2 周内完成,快速试错,不行就干掉,好了就拉一帮人做大做强。对于传统研发方式来说,这似乎非常困难,但是却真实发生了。
在这个前提下,我们的质量效率将如何选择?
开着飞机换引擎会成为常态?基于我们前面的假设,先占领市场,再不断迭代优化,基本已经成为我们软件研发的共识。现在如果有人说,我们是开着飞机换飞机,我可能都只能“呵呵”一声,因为我们自己就经常这么干,对吧。
持续集成面临挑战
再来看我们持续集成面临的挑战:
缺少测试覆盖的持续集成成为负担。当我们单测、API 测试做的不好的时候,通过流程强加的持续集成基本上是自欺欺人,要不就是不稳定,要不就是没效果。
测试团队转型,开发全栈导致的质量下降。有这么多需求,没时间写测试,或者保姆式服务享受惯了,自己没这个意识,等等等等。
测试环境互相依赖产生不稳定因素,在阿里集成环境问题应该是研发过程中的一大痛点。
看了这么多问题,我们需要思考,除了推动完善测试,我们还能做什么?
从工具要效率
好,我今天要讲的是,从工具要效率,质量与效率并重。首先我们看下我们从哪里能获得效率?
第一个快速反馈,我想对于效率我们首先能想到的词是快,也就是快速反馈。加快构建速度,加快回归速度。
第二个是协作,因为往往沟通成本是程序员的一大开销,而且咱们还不太擅长,对吧,经常会发现 IQ 和 EQ 成反比。因此降低协作成本,可以有效提升效率,比如分支开发模式,在线审核,移动办公等等
第三个是创新,原有粗放型,人力型无法延续的时候,创新可能是唯一出路。比如双引擎测试、mock 测试等等。
以上三点我会一一举例来介绍。
协作成本
先来看一个协作的例子,分支开发和主干开发这两种研发模式的对比。
所谓分支开发,就是所有人都在分支上进行编码,比如需求,bug 等等,需要集成时合并到一个临时 release 分支上进行打包发布,发布完成后合并到主干。
所谓主干开发,即开发者直接在主干上进行编码,开发完成后立即提交主干,发布时采用最新主干代码进行打包发布。
好,接下来我们看下两种研发模式的对比:
首先看是否建立分支的区别。分支开发模式每个 feature 都建立分支,利于管控,看到分支马上明白是做什么事情。主干模式直接提交主干,通过 commit 来区分。
第二点,分支研发需要多次集成合并 release,必然会产生重复冲突,集成后测试会导致测试反馈滞后。而主干开发则只需解决一次冲突可以做到提交后即集成。
第三点,当某个分支功能不想发布了,分支模式可以直接退出集成,需要发布的分支重新合并 release 即可。而主干开发往往采用特性开关方式 off 掉相应功能,因为代码剥离比较困难。
第四点,当线上某次发布被回滚掉了,分支模式我们可以把主干进行回滚,下次 release 分支合并时即可自动回滚,防止错误代码被重复发上线。而主干模式需要进行 hotfix,在此之前可能会 block 后续发布。
通过以上四个场景的对比,我们把相对利于协作的标为黑色,不利于的标为白色。可以看出分支模式似乎略胜,尤其是在第三点,基于功能分支的任意集成给研发同学提供了很高的自由度。我们实践下来,通过工具化支持,在微服务人员分工明确,耦合较少和快速迭代的场景下,大大减轻了分支开发集成反馈滞后的弊端。
快速反馈
好,我们看下一个效率点:快速反馈。研发过程中,随着测试用例逐渐积累,测试时间也随之增长,执行时间到 30 分钟时我想应该都忍不了吧,几杯咖啡都下肚了,测试还在跑好抓狂。这里我要介绍一个做的比较有意思的工具来达成快速的这个目标,我们叫他精准回归。他有几个特性:借助中间件全链路 trace 技术,建立测试用例与业务方法的关联关系,当代码变更时推荐需要执行的用例,精准回归,快速反馈。
架构图
来看下这张图。首先我们通过 eagleeye,我们用于 tracing 的中间件插件,来对测试代码和应用代码进行打桩,注入 taceid。当测试用例执行时,我们记录测试用例到应用代码的完整链路日志,也就是 eagleeye log,通过日志采集送入实时计算引擎,计算出测试代码和应用方法之间的关联关系。
打个比方,当我们掌握了一个测试用例覆盖了哪些应用代码后,当代码发生变化后,自然知道有哪些用例可以覆盖到他,这样只要执行这些用例就好了,几十分钟的测试时间缩短到几分钟甚至数秒,对于效率提升会非常巨大。
当然这个方案也不是一点瑕疵也没有,在集成阶段我们推荐运行完整用例集,不过这个没关系,毕竟在开发阶段测试运行的频度要大于集成阶段。
测试创新
先看三个问题:测试覆盖不全怎么办,写测试用例尤其是好的用例需要大量时间。beta 测试会产生资损故障怎么处理,真实流量进入后,如果有 bug,肯定会导致一些问题,虽然影响小,但是也会导致一些不可弥补的问题。测试数据难以维护,经常被污染怎么办,这是一个复杂而头疼的问题。
为了解决以上问题,天猫业务团队诞生了一个叫双引擎测试的平台,通过线上数据采集,线下服务隔离,执行重放和对比,自动完成回归工作,辅助我们提高覆盖率,大大提高效率。
架构图
大家可以看这张架构图,左边是线上服务,首先通过 client 对线上请求进行采集,其中包括 request 和 response,以及下游系统,缓存、db 等等的调用链路快照。通过 mq 消息发送给 beta 环境的 client 进行回放。
这里就简单进行回放请求就完成了么?显然不是,该工具最核心的是对应用所有的下游依赖进行了隔离和 mock,比如应用发送给 db 一条 sql 查询数据,双引擎测试平台会将这个请求阻断,并返回线上同样查询的快照数据。最终拿到应用的 response 进行实时对比,存储不一致结果。
通过这种机制,我们可以轻松实现线上请求,线下回放测试,debug,专注测试业务代码本身,隔离依赖避免干扰。
在这个工具上面,我们还可以长出很多比如用例管理、失败分析,离线回放等等产品,目前该平台在阿里已经形成了自己的生态圈,落地核心应用,并且保障了多次核心代码的重构升级工作。
交付挑战与 DevOps 实践
前面我们介绍了阿里持续交付过去的一些实践,现在的质量与效率挑战,下面我会讲一下我们当前正在做的和正在探索的两个方向,交付和 devops。
国际化和私有云的转变
说到交付这个话题,传统企业一定不陌生,而且可以说是绝对的专家。现在阿里这样的互联网公司面临着新的交付问题。当我们要把电商体系附能给合资公司怎么办,我们要把基础设施和完整阿里技术体系输出该怎么办,当我们应用巨多,形成网状依赖以后怎么办?听着就是一个很庞大的事情是不是?
目前我们的两个交付变化,从统一交付变为分批交付,比如我们先输出电商中台,再输出电商上层业务应用。从整体交付变为分块交付,当全部输出后,要进行版本迭代,如此大的应用规模无法在做整体交付,此时就需要进行分块交付。而且这个块可能每次都会存在差异。这无疑对工具带来了新的挑战。
交付效率挑战
我们接着说效率,我这里列了三点:
快速搭建:我们需要低成本的一键创建环境,复现问题,或者创建交付版本的集成测试环境。
测试回归:当环境中存在多个版本服务怎么搞,而且怎么做到足够得快
链路管理:交付的过程能不能做成一键式,交付的版本能否可视可控,避免交付风险。
下面我们针对以上三点举例说明。
交付过程探索
在这里我把交付过程写到了这个 pipeline 里,依赖识别,对比回归,快速搭建,精准回归,一键交付。
首先看依赖识别,为什么要做依赖识别,刚才提到了,当我的应用数量非常大,并且网状依赖非常复杂时,让人来识别依赖关系已经不靠谱了。而且我要交付一个功能,如果牵一发动全身的让所有关联应用来次整体输出,涉及的团队太多基本也不可持续。因此一定要工具来完成自动的依赖识别。借助全链路调用数据完全可以做到这一点。
比如我修改了 A1 这个版本,通过链路数据结合交付端链路快照,发现必须顺带着交付 B1 和 C1 两个版本,此时系统帮我圈定了一个交付集,后续的测试工作可以基于此来开展。
集成测试开始前,我们可以借助刚介绍的双引擎测试平台进行数据回放,对比测试,确认对交付端数据的影响。
集成测试
接下来我们将进入集成测试阶段,首先是快速搭建,通过应用容器编排,基于中间件隔离,我们可以很轻松的将 A1、B1、C1 进行隔离,形成一个小的集成链路。通过精准回归技术,对变更功能进行快速反馈。
一键交付
最后是一键交付,除了基本的版本管理能力以外,我还可以在集团环境直接管理交付端的环境,让研发人员交付过程成本降到最低。同时在交付端,支持灰度发布能力,进一步减少交付风险。
最重要的还是有通畅的反馈渠道,依靠在前面介绍的平台产品大图上反馈模块的丰富功能比如舆情、问答,我可以快速掌握交付端情况,采取必要措施。
好,以上就是我们针对目前新的交付问题的一些做法,欢迎各位与我深入探讨。
DevOps 之路关键是工具
最后一个话题 devops,在这里我并不会详细展开,只是讲下我们这一年多来 devops 转型的一些心得和一个小创新。
从 15 年开始提转型,阿里集团去掉了大部分业务的 PE 团队,交给开发,16 年我们建设统一调度平台和落地 docker 容器技术,并完成了核心应用升级。17 年可能会是 devops 在阿里最辉煌的一年,今年我们会完成所有活跃应用的容器化和上下游完整工具链建设。
在这里我列了三点,首先对研发来说最基本的 ops 是什么,应用配置、环境、软件基线,线上变更再加上流水线的管控。这是天天在用的。
这么复杂的一套在容器化之前我们做的并不好,当容器化开始落地后,我们的环境进一步标准化,实现了代码驱动变更,管理工具大幅简化。以前的基线工具,软件包校验工具,批量执行工具都不需要了。并且通过配套调度系统,将环境资源真正交到了研发同学手里。
运维系统开始化繁为简,服务下沉,自助型操作转为自愈型,并且开始尝试智能化解决方案。比如大促弹性调度。
DevOps 在阿里
看起来很美好是吧,实际上呢?不可否认,Ops 对开发者是有相当大挑战的,尤其是相关运维基础知识的缺失,解决问题能力的缺失。简单地将 Ops 交给 Dev 就是 DevOps 了么?显然不是,这不但对开发是一种伤害,还是一种效率低下的做法,以前 1000 个人能做的事情,现在需要 10000 个人来完成。
因此我们不能让 DevOps 成为负担,DevOps 机器人在路上。
DevOps 机器人
Devops 机器人实际上是基于数据的主动服务机器人,来随时帮助开发者补充知识,解决问题,并且我们有一个机制来确保知识获取的自闭环。
首先数据来自哪里?常见的,构建错误,机器上错误日志,部署相关的,容器相关的等等。我们首先通过将这些收集起来,再配合用户的行为,比如代码变更 Diff,配置变更等等,保存在数据平台中。
当我们有了数据以后,通过机器学习分析相关性配合人的积累,比如来自专家,工具运营,普通开发者的知识库,形成规则。
当再次产生同样问题时,系统会自动推荐相关解决方案,帮助开发者解决问题,同时收集反馈训练模型。
通过我们的数据积累和问题广场这样的产品建设,形成问题出现 =》方案推送 =》用户反馈 =》知识贡献的闭环。目前通过我们简单的积累就已经达到了 70% 以上的匹配率,未来通过闭环的知识训练相信 devops 机器人会更加智能。
作者介绍
陈鑫(神秀),负责阿里云云效持续交付平台和研发工具建设,致力于企业研发效率、产品质量、DevOps 方向研究和探索。在阿里 6 年带领过大数据测试团队、测试工具研发团队、持续交付平台团队。对研发协同、测试、交付、运维领域都有很深的见解。