持续集成的平衡之道

  1. 云栖社区>
  2. 博客>
  3. 正文

持续集成的平衡之道

mongolguier 2018-01-31 21:07:41 浏览1646
展开阅读全文
摘要:从亲历者的角度向大家分享从传统软件企业到Saas服务化企业,持续集成转型的感想,踩过的坑,受过的伤以及甜蜜的果实。也会分享一些特定场景下的技术管理+持续集成的落地方案。

本次直播视频精彩回顾,戳这里!

演讲嘉宾简介:
戚俊,南京路特软件CTO 。身处媒体大数据行业,热衷学习、实践新技术。自12年起主导完成了公司所有业务的云端转化,专攻产品性能优化、自动化运维、平台架构设计工作。同时是一名资深的阿里云产品使用者,擅长基于阿里云产品体系完成高效、高可用的产品架构设计。

以下内容根据演讲嘉宾视频分享以及PPT整理而成。

本次的分享主要围绕以下五个方面:
一、遇到的困境
二、敏捷开发与持续集成
三、技术流程模型
四、持续集成与工具链
五、持续集成与架构
六、总结及阶段性收获


一、遇到的困境
虽然持续集成这个概念提了很长时间,在互联网界非常火热,但是问问到底谁在用,或者问问谁用得好不好,最后会发现其实凤毛麟角。从入了持续集成这个坑,遇到的问题会很多,下面总结了三个主要的问题。其实这三个主要的问题,不仅仅可以放在持续集成上面去说,对任何一个互联网公司,要去做改革的话,这三个问题都不可避免,第一个就是成本问题,第二个是管理问题,第三个是效率问题。这三个问题在后面引申了几条遇到的一些具体的表象特征。
4818666fd4ebce17f8da940d2f99567d48cf9070
第一个问题,人力成本。对于企业或团队,会认为需要一个专门的人来进行代码的审查和合并,这是目前比较常见的一种心态。对于大部分的CTO、技术总监、项目总监,思考这个问题会比较频繁。对他们而言,希望开发人员,测试人员的工作是OK的,并且是风险可控的,风险可控并不是说业务风险要可控,只要代码不写错就行了,而指的是内部流程上的可控。有时给内部团队过于的自由,导致出现了很多的问题。比如说开发,随随便便写一段代码,然后可能在他看来实现了一个基本的逻辑功能就OK了,甚至测试都测过了,但是,因为没有去对这一段代码进行审查,然后最终上线之后出现过大量的性能问题等等这些问题,其实是比较频繁的。在这时,需要一个专门的人来做一个审查和代码合并的工作,那么带来的问题就是,可能会承担一个额外的人力成本。

第二个问题,资金成本。如果要去做持续集成,就需要为持续集成的基础设施付出成本,成本指的是金钱成本。比较常见的就是如果说要用到一些持续集成的工具,如Jenkins, Jira,等需要去部署,部署的这些工具就会产生成本,服务器带宽,运维的人员也会产生人力成本,这一块就是资金上的一个成本。

第三个问题,时间成本。一旦选择去做持续集成,在这个过程中遇到各种各样的,持续集成工具链中的问题,并且有些问题能解决,有些问题无法解决。因为持续集成这个泛概念在中国是比较流行的,但是具体到操作,有太多组合的可能性。从一个代码的管理角度来说,即便从最开始的,从跟踪使用什么样的工具,是使用Jira,还是使用别的工具?从第一步,分歧就开始了。选择使用一个什么样的工具,以及这个工具后面衍生出来的一个工具链,都会产生这样的问题。那么,如果你用的这套工具链中,有你不熟悉的产品,或者有国人不熟悉的产品,在解决这个工具链中遇到的问题的时候,带来的苦恼就会非常的大,幸福感很低。这是第三个问题,时间成本。

第四个问题,管理成本。在管理过程中,找不到一个合适的姿势来维护企业和团队内部的一个代码权限。对于多产品公司而言,一旦选择使用如Git这类公网平台,带来的问题就很突出,需要为开发人员开放足够的代码权限让他去进行开发。但是考虑一个问题,当一个员工入职,离职,或岗位职能发生变化,这个人的代码权限怎么调整?谁来调整?如果没调整会发生什么后果?

最后一个问题,效率问题。以前在发布一个大版本时,希望整个公司的人都到场,这是大部分的中小型创业团队都会存在的一个明显的问题。这个问题的背后其实是一个安全感的问题,也是一个效率的问题。


二、敏捷开发与持续集成
平衡敏捷开发跟持续集成之间的关系,需要解决的下面三个核心问题。第一个,从整体的目标去出发,需求以及bug如何尽快的进入开发流程?第二个,开发成果如何快速试错?第三个,如何依托持续集成完成快速迭代的全流程?
a392382ab0db94c7a98826bc2ce5615fe498df48
第一点,一些需求和bug是从客户反馈回来的,如何把它转换成系统内的需求点,功能点和bug处理的任务节点,这些问题如何去转化?另外,体制内自己产生的一些bug,比如,测试人员,QA人员对产品进行测试的时候,发现了一个bug,便反馈给开发人员,这也是需要解决的一块。以及产品经理,甚至销售人员,对产品提出了新的需求功能点,这些点如何尽快进入开发流程。这一问题是敏捷跟持续集成的大前提,如果要结合持续集成做敏捷开发,这是一个越不过去的坎,必须做,且要做得比较好,否则无法实现敏捷。如果为了做持续集成而把一个本身很敏捷的团队变成慢慢吞吞的一个团队,那就失去了持续集成的意义。

 第二点,开发成果如何去快速试错?因为往往有些功能,甚至是产品经理决定做某个功能时,都无法确定这个功能是不是最终客户会认可的功能。在互联网创业型公司或者是互联网的公司里面会存在这个问题,产品经理,老板或者团队的领导,决定要上某个功能,然后在上这个功能的过程中,只能凭自己揣测的想法,没有一个非常完备的调研。只能决定先上架,根据客户的反馈,再决定两个分支方向。客户的反馈不错,那决定对这个功能进行一个加深改造,客户的反馈很差,把这个功能砍掉下架。这种事情是在最近几年是比较频繁的。

最后一点,如何依托持续集成完成快速迭代的一个全流程?因为目前来说,市面上能找到的一些持续集成的开源工具,只能完成技术层面的整合,它对项目管理,产品管理和质量管理没有太多的帮助。并不是做产品质量管理的跟踪工具不多,而是一旦要结合持续集成,这种工具或方案就很少,换句话讲不太符合国人的习惯,也不太符合现今中国的互联网公司运转的规律和速度。因为国外的用户在用的时候,跟我们国内的用户,从使用的角度和使用的习惯上来说,是有很大的差异的。这一点有可能会导致天差地别的一个改变。


三、技术流程模型
下面分享的是公司内部的技术流程模型。排除掉前面一些bug入库,需求入库,产品文档和进库以外,技术流程如下图。
ed64ecc36a9cce48857f0384ccacb508cd81b0ec
第一步,过滤掉创建仓库这些基础操作,开发人员去拉取一个dev的分支,假设开发人员叫韩梅梅,命名为dev-hanmeimei。她在自己的分支上进行开发,开发完成之后把自己的个性化分支合并回原来的dev分支上。因为如果主干目录开放给所有的开发人员去进行同时增量的进行开发工作,发现一个最大的问题就是时间差效应。比如当安排多个开发人员同时去开发一个产品的时,由于每个人有不同的功能上限节点,当某个人发布的时候,另外的人可能只改了一半,已经提交了,这会导致产品界面残缺,界面功能互相影响。所以在这种情况下,反过来做一些调整,把主干分支永远作为一个合并类分支,不允许任何人进行手段操作,dev分支去进行一个统筹管理。这个分支只允许人去进行合并,而不允许人进行提交,防止我们的主干分支被污染。这样可以完美的避过时间差效应。

把dev-hanmeimei分支合并到dev之后,就需要对dev分支进行一个构建并测试。对于构建,简单来讲,结合各个语言,如Java类的编译型语言,需要把它生成一个Jar包或者生成一个War包,如PHP这类脚本型的语言,需要对它的第三方的包进行一些管理,或者对它的一些配置文件进行管理。对dev分支构建完成之后去进行测试,dev分支如果测试通过,代表开发工作结束。

把dev分支测试完成并且通过之后把它合并到rc分支,rc分支同样是不允许直接改动代码的一个分支,只接受从dev合并到rc。合并到rc之后,同样走一次构建过程,然后构建完成之后进行一次线测。

大家也有可能注意到,在持续集成这个领域中,大家越来越关注的一个点,在部署过程中或者在线测过程中引入了一些新的机制,比如说蓝绿发布,或者灰度发布等。因为开发人员本地的数据,跟线上的数据可能有一些差异,线上的数据的可能性永远是出乎意料之外的。测试人员在本地,可能选择一个合适的年龄字段填一下,不会想到极端情况,但是线上的用户,填写几千岁、几万岁的情况也会发生。这种变化反馈到最终的结果可能是很失败的一次迭代。所以在调整完成之后,在现测这一步进行一些灰度发布,或者按比例的给客户推送。

当RC结束之后,把它合并到release分支,是一个存档且最终用来维护的纯净代码分支,这个分支是线上最后一个版本。release分支并不意味没有bug,无法确保没有任何bug。出现bug之后怎么办?第一种通常直接把release分支迁出,直接改bug,改完之后再合并回dev分支。第二种是把release分支迁出之后改完bug直接发布,因为这时有一些bug是非常紧急的,需要短时间内把bug修改完毕,所以在这一步是允许开发人员,直接迁出release分支,迁出之后直接进行调整,比如迁出一个release-hanmeimei,改完之后,合并进来。

只做一个产品的公司是很幸福的,然而对于多产品线的公司而言,当每一条产品线功能不一样,代码不一样,如果按上面设定的这条路线去走,会非常的累。这就会涉及到上面提到的问题,从一个敏捷开发的模型,为了做持续集成这件事,成为慢慢吞吞的开发团队。因为开发人员并不是特别的充足,或者说每一个软件公司的开发人员永远不可能有够的时候,三十到五十个人其实并不能做太多的事情,特别产品线变多,又有交叉,这种情况下是很难做一个贴切并且舒服的持续集成的一个流程。后面针对这种模型去介绍对应的解决方案,包括一些行径路线,解决痛点的工具。


四、持续集成与工具链
平衡,要考虑持续集成与工具链,持续集成可选择的工具还是有很多的,下面简单介绍一下。
c635942a69b76dd25b0b762e3454783c72eb2136
2015年开始做持续集成,用自建脚本来解决构建和部署,那么自建脚本怎么去做?比如有Java源码,通过自定义的Python脚本,把原代码通过FTP下到某个机器上,然后在某个机器上装好JDK的固定版本,定时的用Python去调命令行,RUN一下JDK构建的命令,把它生成一个Jar包或者一个War包。这种方式比较原始,出错率很高且FTP并不是很安全。

从2015年底到2016年初的时候,尝试了阿里云的CRP平台,是阿里自己去做持续集成的一个工具化平台,用了不到半年时间,没有用全它的所有功能,只用它去做了一个简单的构建类工作,后来便放弃了。原因是当时计划转成容器化的方式去做,因为当时CRP不支持容器,也不支持Docker。

之后使用Jenkins工具,做了很多的方案。因为为了使用Docker,只构建这一步便浪费了大量时间,用了至少三个节点的机器做Docker镜像的构建。因为每一次Push代码都构建一个镜像,当发版本比较频繁,或者开发人员提交合并频繁,一天构建会几百上千次,一个Jenkins节点构建的时候,CPU就达到100%,然后挂掉。后来全部改成分布式构建结点,虽然问题解决了,但是也不是解决的特别好,因为无法确定何时会出现一天内比较频繁的提交请求,最终定成每五分钟构建一次,无论提交与否,错开峰值,解决了一部分的问题。如果说对于只有几款产品,或者说代码的种类产品数少的公司,考虑用Jenkins是没关系的。

最后放弃了Jenkins,转到了阿里新的RDC平台。因为RDC平台是支持从项目的管理,需求的管理,缺陷的管理,跟踪,构建,到部署整个全部流程。如前面所提到的,没有一个很好的软件或者是几个工具,能够完美的解决持续集成中整个闭环问题。RDC这个工具是目前使用到现在为止,少有的能满足90%以上需求的工具。目前来说是免费的,而且它的构建也免费的,相对来说比较省心。


下面在用这个工具的过程中,踩过的一些坑跟大家分享一下。
0a5f19b9f44235d2650a83bb9e58fb38f80564fb


用户的坑。部署一个开源工具(Jira,Jenkins等),之后需要进行用户管理。问题回到本文开头部分的问题,如何去管理用户?对新入职的员工分配一个权限,对离职或调整岗位的员工,需要把他从这个权限中摘走。这些琐碎的问题很多,非常困扰。    

碎片数据的坑。虽然每一个工具都很强大,但是到最后会发现,缺陷跟踪,需求,全部都放在了Jira里,构建日志,部署日志,全部都沉淀在了Jenkins里,这些问题最后如何合并起来?有时想回顾过去犯下的错误,但在分析这件事情时会发现难度之大超乎想象。

运维的坑。首先是软件升级问题。因为开源工具的版本迭代非常迅速,3-5月不迭代不更新,版本号或许已迭代了十几二十次,到后面需要更新的时候,连文档都找不到。除了软件升级问题,持续集成工具的服务器结点的运维,有时会莫名其妙的出现问题,特别是Jenkins工具,这个工具总是在不经意间给你带来很多的麻烦。


五、持续集成与架构
调完了需求、项目管理以及工具链之后,因为持续集成跟架构有一点关系的,大家可以参考一下整个的行径路线。
2538ef8588d0e81da7e6dd31888c1cadc15adaa6
在起初做持续集成时,是双平台,多语言,.NET和PHP一半一半,以及少量的Java。PHP和Java全是Linux的,只有. NET部署在windows2008和windows2012上,由于历史遗留问题,只能想办法把这个问题消化掉。第二步是去半容器化,为什么做成半容器化呢?也有一些历史原因,是因为.NET容器化不是很顺利,当时官方对.NET的接入微软平台并不是特别的好。直到2016年年初,Docker对.NET的支持才有点起色,在2017年,.NET已经可以进入业务环境执行。

在2016年年初,做了纯粹的容器化,所有的业务环境全部迁移到Docker平台,使用的是阿里的容器服务。在这两年使用阿里容器服务的过程中,虽然发现过问题,但整体而言,这个产品还是不错的,客服的响应和迭代比较快,在容器化的过程中重写了所有的.NET应用,改成PHP版本,或.Net Core版本。现在已经完整的支持了多语言,全容器化,对本来的版本没有什么太大的伤害,得益于全球的容器化的进程。

现在停留在第四步,将所有的应用通过解耦拆分方式,变成微服务进行部署集成。但是对微服务希望大家慎重。目前来说,对微服务还没有找到一个十分舒服的姿势去看待这个问题。微服务不像持续集成,对业务立刻有帮助,它是在业务达到一定规模之后,一定有帮助。但并不是现在就要去做,所以对微服务这件事情,可自行参考。

下面简单介绍,在做了持续集成之后,结合阿里云的服务器做的架构。
73ee616d55d7232f0e2de9c279be18340a0e93a0
用户从公网的一个固定IP进来,之后直接进入到我们的Docker集群中,Docker集群是通过解析来路域名和来路端口把流量去分发到不同的容器里面。这一块流程阿里现在已经全流程打通,当然也是依靠的Docker官方的基础知识。现在阿里的容器服务支持三种模式,一种是早些时候的Swarm模式,正在测试的Swarm mode和比较火的在国内外比较火的K8S三种集群模式,大家感兴趣的可以体验一下。

我们都是通过一个统一的S NET服务器出公网,所有的集群里面的机器出公网都是一个IP。一个优势是可以通过出公网的IP控制白名单,这样可以避免跟第三系统去对接的时出现几十个IP去对接接口,一般第三方是不允许这种情况的。上图中是所使用到阿里的产品,这个架构是2016年底到2017年全年都在用的架构,原来没有用这个架构之前,大概有60台服务器,现在大概缩减32台,每年省下来的钱大概是二三十万。


六、总结及阶段性收获
在做持续集成是这件事情上面,一直在做的就是寻找平衡。从2015年开始做持续集成的架构调整。原因方方面面,主要是已经厌倦了高薪水的开发人员做一些低级的事情。

2015年开始调整的时候,早期的使用SVN,后来转成Git,这个过程中大概持续了三个月,代码全部修改。之后用自定义的脚本去做构建和持续集成,做部署。再后来就是调整为容器架构。之后是阵痛期,CRP,JKS,RDC这三个产品拉锯抉择,最终决定使用RDC。RDC这个产品已经改名为云效,域名依然是rdc.aliyun.com,有兴趣可以去体验一下。 在2017年末,基本上全部迁入RDC,目前来说我们正在跟这个产品还是蜜月期,提供的支持和力度都还不错。
9096c9a0345808346013372d0d71e210a7ddef4f


目前获得的收获主要是以下三点。第一个阶段性收获,通过阿里云系列服务及本身架构上的调整,成本上已有比较大的节约。其中,持续集成的节约是一方面,通过做持续集成,架构上的改变会带来一些成本上的减少,大概每年在20到25万左右的节约,这个费用省下来,可以对产品有一个更好的一个增进。
c657f73ca7d3a31fa8d5c4dc9ff94cf9b14c01a6
第二个收获,钉钉可以跟云效(RDC)产品做一个深度整合,帮助解决所有的帐号问题,代码的权限问题。一家用钉钉的企业,员工入职之后,就会自动出现在云效(RDC)平台里面,在云效(RDC)平台里面,只需要为这个用户规划一个组,就可以拥有一些对应的权限,如Git的代码权限等,相对来说比较简单。也可以直接通过他的权限去完成构建,测试发布。这类工作以后不需要有一个比较高级的人员,频繁地做这种低级的事情,通过与钉钉的有机结合,可以变得更敏捷。而且目前钉钉支持把一段聊天记录直接转成需求,或者转成bug,这个方式相对来说值得一试,对项目管理的提升是最大的。

最后,多产品项目的持续集成通过云效(RDC)的自定义流水线,降低了中间成员的时间成本,并且提高了效果。原因很简单,原来发布版本时,往往希望整个公司的人都到现场,原因是开发人员有时候没有足够高的自主权可以决定这个版本是否要上,出了问题是否回滚,甚至小一点的团队领导也没有这个权利。出了任何事情,开发人员需要征求项目管理者,遇到bug是回滚,还是后面再改bug,这占用了大量其他人的时间。现在通过自定义流水线的方式,可以开发人员直接发起一次请求之后,请求通过就可以发布了。前面所有的流程,包括构建,测试,打包,上传包,上传到测试服务器和线测服务器,都可以由开发人员完成,只有最后一步,确认发布到正式平台,迭代时,一定要某个项目管理者才可以发布,回滚也是同理,非常安全,且节约时间。
 


网友评论

登录后评论
0/500
评论