开发者学堂课程【ALPD 云架构师系列:云原生 DevOps 36计-阿里云云效出品:研发模式的三个实践案例】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/772/detail/13515
研发模式的三个实践案例
内容介绍:
一、P2P 直播 CDN 产品
二、基础网络产品
三、金融安全产品
四、总结
一、P2P 直播 CDN 产品
增值模式是跟产品的形态和团队对相关,第一个案例是一个 PNP 的直播 CPU 产品,如题式架构图。
平均分成两部分,一个客户端一个服务端,客户端是有多端的,比如手机,路由器机顶盒,安卓 iOS 各种端,每种端的发布形态,是不一样的,终端跟客户端跟服务端之间有两条,通讯录一条。另外一条是控制数据链路,然后服务端,包含了三部分,简单来讲三部分,控制面,用户,以及是数据运营和监控的服务。
每一种都有包含很多个具体的应用,比如用户面控制,每个可能都有十几个二十个应用,整个的架构就是如图上左边显示的样子,团队是一个十个人左右的点评团队,没有专职的测试和运维。有十个人,十个人就基本上可以认为大家都在做产品,所以团队因为大家在一起整个都是很紧密的,工程能力还可以,会有比较多的单元测试和功能自动化的保证,基本上可以做到一个比较快的一个测试反馈。技术背景是 C++为主,因为业务的特点,一般来讲,对于内存对需要性能是比较关注的一款。来看它有两种应用,一个叫服务端,服务端因为是 C++一般都都通过源码级的依赖去做构建。然后运行时基本上除了配置中心之外就没有其他内容了。
太多其他的依赖,共用时大概30个,一次应用一次发布,每个应用是可以独立发布的,所以不存在发布的依赖性,编排问题由于网络问题很多时候是需要物理机部署,比如没法用K8S和容器的方式,客户端是多端的,所以是一个代码库,一个代码多个件,但是同样是没有运行依赖的,有的是热更新,可以用版本就可以了,但有的需要通过应用市场去发布,比如iOS那就只能够保持很多的版本,发布频率不太一样,比如一般是最多一周一次,导致肯定会有很多长期的存在更多版本存在,看一下案例里,是怎么支配它的服务端和客户端去做研发模式的设计呢?首先看一下服务端:
服务端是一个看上去比前面PDB还要简单的一个模式。因为人很少,服务差的足够小,差到几乎就是每一个服务可能就是一到两个人在改,所以这种情况下,就没有必要再去搞例子分支,在一个主干上开发,开发一个问题是一个服务。基本上可以是一个服务,一个库,而且服务差的很多很好。
所以平均一个人大概三四个应用,所以服务很好。这样的情况下有一些自己的一些纪律,比如因为要保证多端,而且要保证客户端的版本,所以代码必须要保证向前兼容,同时代码是直接不需要master上的,所以不存在刚刚的要合并问题,然后在整个 Mac 上的一段代码提交之后,会有对应的自动测试,如果测试失败,是有的几率是提交者需要在一小时内去修复。什么时候发布呢?
在 master 创建,一旦打开就发不了,tag会触发一条流水线,流水线会去做一次发布,如果出问题之后怎么办呢?不管老的版本,永远用最新的版本,出问题之后,就在最新代码上去修复,永远发布最新的版本。这就是服务端的一个流水线。如果团队可能也是类似的情况的话,建议其实可以尝试一下,因为真的相当简单,而且基本上如果做好纪律,可以做到很高效的一个发布,从反馈的角度来说是特别快的,特别同学一旦出现了问题,要想要学习需要去修,不然等不下去了,还可以后面再去修,这时就会延迟反馈,上一节课也讲到了,是反馈带来很多的问题,客户端形式就不一样,客户端有点像PNP的玩法其实基本上就没办法了,平常还是用主观来开发代码最新代码放在桌上做提成,但是要发布的时候,是会拉一个例子,因为客户端有两个特点,一个就是发布和升级是比较困难的,所以需要做足够多的发布前的验证,这种情况下,就需要一个例子分支去保护。
同时就是会要去考虑包括其他的问题,因为会同时存在多个版本,然后另外就是5/6要保证活跃度根本尽可能少,所以一般只关注最新的活跃的粒子分值。
在这种情况下,就是TB是一个非常合适的一个方式。这里也是针对发布来说会做相应的分析的隔离,另外一个发布是因为要相对来针对版本有一定时间的一个维护确实需要一个相对长期的一点。比如下一个大版本又要开发,上班可以不管,但一般会维护至少一两到三个版本。
其实从当时产品的真实的经验来看,长期存在的版本数可能超过十个,因为没法去任意的去升级,会有各种各样的原因升级不了。
发布的版本的一个管理或者维护。所以就会考虑尽可能让能升到最新的版本,如果做不到还是要在脑子里想象如何完成的。
二、基础网络产品
案例三是一个相对偏底层的一个产品,是产品虚拟网络的产品,可能很多外部做一些底层的一些产品的公司,可能遇到类似的产品,那整个是50个人左右,每个团队大概十个人数,大概五个团,团队的协作需求是挺高因为这种产品,一般都是一起发布一起继承的,是一个完整的东西,但是开发是放在好多同学开发的,整个团队的工程能力适中有单元测试,但是其他的测试的保护。
后面测试主要是靠具体的环境去测。开发语言C++为主,应用是一份代码,但是也是多端口,要应对多种的硬件和高雄的市的区别,底层依赖APP,就是虚拟层,然后以及硬件内侧,升级的时候是需要停机的网络的问题,不能很容易的做到热更新,然后一次发布一个应用,但是发布是有顺序要求,如果有好多应用,真的发不是有编排顺序的,不能随便发。发布周期是很长的,整个更新周期一般需要几个月,所以几个月才能做发布。
所以同时可能会存在说两个都在,都在走地发布,比如一个走了80%,另一个承载了10%。如图:
这种产品,怎么去设计它的一般模式呢?特点跟刚刚的是很不一样。也是跟前面客户端的发布有点像,但是履历分支会更长,而且版本是需要固定下来的,又要明确的探索,所以要回 master,所以特点是什么?
就是 master 是不能直接提交的,永远是指向最后一个已发布的版本,整个开发是拉取 release 去做的,例子可能会比较久。在做完之后,在APP上做完整的测试评审,发布之后合进master。就有点像项目制,就是一个例子,相当于一个项目从master上拉出来之后,所有的开发和发布的工作都在release分支上。
这一个release分支就相当于项目的一个版本,在基础上去做release分支就进入到了维护阶段可能对另外一个项目,就比如release 2.0做相应的一些开发工作和发布。
到一定程度之后,release 2.0又会进入到一个维护阶段,所以是按这样的一种分支模式。所以区别就是tag是打在了release分支上,或者master是发布手法,对master,永远只做机械用来管理。案例二就是另外一个产品。如图:
三、金融安全产品
一个金融领域的安全产品,产品特点跟区别不一样的,是什么呢?同时提供两种交付形态。产品一份代码,提供两种药品的,一个SaaS的,一个是私有化交易。
整个应用架构,其实相对比较简单的。有些后台服务,客户用去接API服务然后有控制台用来做配置,后台服务里面的API会掉很多,这是典型的大数据的一个场景,包括一些人工智能的一些产品,都是类似的一个架构。
整个团队的话,是在150个人左右,但是特点就是前端算法,后端所设置专门的职能团队,没有运维,团队一般需要协作才能完成,因为往往是不会有一个需求落在某一个团队,然后工程能力一般,没有单元测试和自动化功能测试,这样一些守护的基本上就是靠后续的人工测试来去保护质量,整个技术是以Java为主方式去部署。那它的应用特点是什么呢?
就是安装包很多,然后就是依赖,最好不要用Snapchat,但是实情况是很多的例子都有那种依赖,其实是不确定的,然后应用的运行时也有很多的依赖,比如API依赖身为主人,API依赖的指标计算,类似这样的依赖其实很多,总共用数大概20个,发现就是这两个的很不一样,100多号人,就20个应用,前面是可能有十个人有三十个人,用的比较大,一个应用是很多人协作的,一次发布网一组用不是一个应用,然后 SaaS 版本和 C++就不在一个版本上,会落后相对几个版本的情况。
所以这样的一个产品和一个团队。看到就是像刚刚的案例,但区别就是没有第八部分,只有 release 分支用来做了集成分支,但是临时的,master分支还是发布,分支永远是指向最新科目代码的,多了一个例子,分支例子能用来做临时的继承。比如作为私有化来讲,可能一个月发布一个版本,这一个月的话,就会拉一个例子。就和刚才所讲的项目直向下比较像,但是,是短的,提升完之后,会和master去做发布。所以这里 release 更多相当于是一个迭代的一个分支,但为什么需要做临时的分支呢?
因为刚刚整个测试,是比较长的周期,同时也要维护多个版本,所以就会有多个并行的例子。
四、总结
举到了三个例子去说明一下分支方式,通过例子其实也可以发现,其实所有都是根据团队,本身的产品的一个特征来确定一个分支模式,使得这些分支模式采用的基本上也尽可能少的。
然后让分支维护成本相对要低一点,因为每多一个分支意味着维护的成本就会高很多,所以在过程当中,在选择分支的时候需要合理的去考虑,比如还有一些其他的场景,比如在集成过程当中,集成进去之后,发现极限分支出现有问题,需要把相应的一些代码给摘出来,有类似这样的一些诉求,就是很多feature分支合在一起,这时想摘出来,但是合进去了之后想再摘出来就很难摘了,要去解决掉一颗老鼠屎,坏了一锅汤的这种情况,其实也可以用相应的分支,比如临时的集成分支来去解决,当集成分支失败了之后,发现有问题,临时再拿一个提成本金。
只要将不要的分支摘掉,然后把其他的合进去,所以发现其实很多时候分支其实是可以很灵活的来去使用的,但是灵活地使用也会给程序员带来特别多的理解和维护的成本。建议就是分支应该越简单越好,另外一个尽可能减少程序员关注分支。让程序员只关注在自己开发的本质上。那就好了,所以这里给出了一些实践建议。
实践建议
- 单主干:一个代码仓库应该保证有且仅有一个主干分支。
- 最少长期分支:在避免冲突的前提下,尽量减少长期分支的数量
- Promotion:代码的提交应该是逐级合并,如feature->develop->master,避免feature->develop和feature->masterf同时存在
- 发布不可变:发布的版本应该是不可变且可回溯的
- 自动化事件触发:分支的持续集成过程应该是自动化的,且通过代码提交事件或制品变更事件自动触发
Takeaways
- 团队研发本质上是一个异步的、延迟协作的过程,随着产品复杂度和团队复杂度的增加,协作成本快速上升。
- 研发模式的本质是为高效交付需求,研发团队围绕代码库的一系列行为约束。
- 通过分支进行隔离,避免冲突;通过小批量频繁提交,减少等待。
- 控制分支需要考虑最大化生产力及最小化风险。
- 分支的选择需要综合团队规模、协作成熟度、产品交付形态几个要素。
团队研发本质是一个异步和延迟协作的一个过程,随着产品的复杂度和团队的复杂度增加,成本也会增加。协作里成本会带来很大的一个问题,就是冲突和等待,所以在研发模式的本质其实是围绕代码库的一系列行为。
所以通过分支进行隔离,可以避免分配,然后小批量频繁的提交,保持信息同步来减少等待。减少分支的维护和管理成本,同时分支可以用来去做下一些隔离,但是频繁的提交,还有分支之间的信息同步,然后来减少彼此的等待。那另外一个,就是分支的选择。选择需要综合团队规模、协作成熟度和产品交互平台,此要素刚才也举了三个主要的例子。
另外一个很重要一点,就是分支的模式和整个持续集成和持续发布的一个策略是息息相关的,就是从简单的组合的角度来讲是主干开发,主干发布,分支开发,主干发布或者分支开发,分支发布,或者主干开发,分支发布,Anyway 其实是如果持续发布,就是主办方的方式就好了。通过 release 方式来发比如需要去做相应的bitter 之间的隔离,就用分支开发的方式,这是简单今天的课程的一个总结,其实分支方式,分支模式其实相对来讲不复杂,很简单,概念也就这些。很多时候要靠大家平时之间平时在注意自己的场景,做相应一些选择实践。团队随着团队规模的变化,成熟度的变化,也会做调整,其实并不是一成不变的。
今天给了好多好多事例,可以选择一个或者多个,去走一把就配置一个流程。
因为其实给代码,在运销商可以类似的去做一把,把流水线和配置保护策略配上去,因为在应用代码里其实放了很多的 to do,是希望大家能够去本地做了几个。
然后第八个就是个可选择的,可以思考一下,如果有一个依赖两个应用的需求这时应该怎么做,比如应用有什么要求,对工具该怎么做,也就是一个需求涉及到两个应用,这时该怎么办, 还有另外在基础上,还可以再去想想,如果一个产品涉及到很多很多应用都要一起去发,而且是版本的方式,就像前面就是策划的那种。
怎么去设置分组模式?其实讲一个题外话,就LPD讲领域驱动设计。这时发现很多开发者参加课程,因为觉得听完课时候,可以成为一个很好的架构师,和一个很好的程序员,针对工程实践的问题。课程里也有一个很小的愿望,听完课程之后,可以成为一个 develop the divorce的一个master,可能不是一个特别一个,比如听完项目实践成为项目经理或者另外一个架构师,因为工程实践更多的是涉及到一个团队,一个组织,一个公司,这里希望大家听完课程之后,能够在公司里很好的去把相应的一些工作实践能够做相应的一些升级。