电话

15169028800

架构漫谈:软件的架构拆分之道

标签: 软件开发架构 2023-06-09 

  软件需要拆分,这是众所周知的。但是如何拆分,根据什么原则拆分,则众说纷纭,各有各的道理。

  本文是的第十篇文章,作者将会重点谈软件拆分背后的原则和原理,对于我们每一个人来说,理解这些背后的原则,可以让我们在复杂的情况下不再迷茫。如果我们每一个人在自己的能力范围之内,尝试往这个方向努力,真正的为软件开发的环境带来改变,这就善莫大焉了,这篇文章的目的也就达到了。

  软件需要拆分,这是众所周知的。但是如何拆分,根据什么原则拆分,则众说纷纭,各有各的道理。甚至有人认为把架构一步到位的做好是不是更好?还有很多人根据自己的经验从技术的角度去进行主动拆分。因为从技术上讲,每个人对技术的理解都不太一样,都有自己的侧重点和道理,拆的方案都是符合自己的利益的。

  “别人”的问题能否得到很好的解决呢?是不是反而拆出来更多的问题,导致更加恶化?在实际的操作过程中我们更多看到的是:系统遇到瓶颈,被迫加班加点的进行拆分,并把这个叫做架构的演化。以下打算探讨一下软件拆分的原则和方法,可以把本篇看做的进一步细化,请大家结合起来阅读。

  软件架构拆分的原动力实际上是来源于业务本身的切分所形成的组织架构。这个似乎比较难理解,我们先从业务本身分析。业务的组织架构是怎么形成的呢? 业务组织架构的背后原动力,如架构漫谈第四篇所说,是每个人的负载超限。这个负载主要是人的时间不够,无法在一个人有限的时间内完成大量的业务,就只能把整个工作的大的生命周期,切分为小的生命周期,形成一个树状架构,授权给具备不同专业技能的人对各自所负责的生命周期负全责。

  而分拆的人则成为了整个组织的领导,负责把各个子生命周期的运行结果组合为自己的产出,这样他一个人在相同时间内的产出就放大了许多倍。比如一个公司刚开始时,CEO一个人处理所有业务。这个时候客户比较少,问题还不大。

  当业务逐渐上来,客户量和业务规模逐渐上来的时候,CEO一个人就不可能做所有的事情了,自然就把他自己做的所有的事情(也就是整个公司运营的生命周期),切分为更小的生命周期,分配给不同的专业的人来运营,形成一个树状的架构:

  当然,每个专业领域还可以把自己的生命周期细分解成更小的生命周期,以提升自己的生产力。但是当增长到一定程度的时候,沟通成本就成了主要的损耗,不可能无限的增长下去。所以引入软件系统来提升生产力就顺理成章了。软件实际是扮演一个替代人的作用,把很多人做的事情,交给软件来做。如果业务人员能够进行软件开发,那么这是最好的(未来应该是一个趋势),他们自行把自己的职责自动化,就可以提升自己的生产力。但是实际情况是,软件开发门槛还是很高,所以必须成立独立的软件开发团队来服务于业务人员。

  以上看起来好像说的是传统企业采用软件的过程,但实际上是想说明企业背后架构发展的逻辑,并非特指传统企业。互联网企业的发展也是一样的,和传统企业的区别在于,互联网企业一开始就专注于采用软件来提升生产力,业务团队的增长往往会慢于软件体系的增长。因为软件强大,业务人的生产力提高的非常快,不需要大量的业务人员投入,但需要大量的软件开发投入。但是绝对不可以因为没有经历无软件的纯业务期,而忽视业务团队,放弃以业务为中心。因为软件是为人服务的,是为业务服务的,先有人,有业务,才有软件,这个次序绝对不可以颠倒。没有人,软件就失去了模拟的目标,软件就没有价值了。

  因为需要把业务部门提出的需求用软件来实现,自然需要建立软件开发团队。那么对于不同的业务团队提出的需求,软件开发团队又应该如何分工组织来应对呢?我们分几种情况来分析:

  在这种情况下,很容易就出现软件开发团队中的某些人会处理多个不同业务团队的问题,进而就很容易导致多个不同业务团队的需求,以省力或者重用的理由,全部或者部分的整合在了同一个软件中。这样就会导致这些业务部门都在提需求的时候,软件开发团队内部之间,软件开发团队和业务部门之间,会产生大量的互相依赖,干扰,扯皮,也会产生大量的会议,降低整个团队的效率。最终这些软件之间的依赖状况会变得错综复杂,软件上线也会变成一个纯靠运气的活了。

  在这种情况下,业务团队必须要自行对业务需求拆分,以便给到相应的开发团队。而业务团队一般都不具备这个能力,只能同时和多个软件开发团队一起开会讨论,同样会有很多的沟通,扯皮。并且这种沟通是持续的,每次调整都需要所有团队来开会,效率非常的低下。并且初期的分工所形成的职责切分,随着沟通的进展,会变得越来越模糊,最终也会变成和情况1类似的情况,软件的之间的依赖状况会变的错综复杂,软件上线也变成了运气活,要烧香求神了。

  这样每个业务部门都有独立的软件开发团队来配合。这些软件开发团队只对应一个业务团队,所形成的软件边界都很清楚,沟通也很高效,业务团队和对应的软件开发团队能够形成合力,共同解决该团队的业务问题。这实际上形成的还是一颗树。

  由以上对比可见,情况3是最好的状况。每个业务部门形成了一个软件开发团队,这个软件开发团队为这个部门生成相应的软件,提升该部门的价值。当然,如果业务团队内部划分为多个子团队,软件开发团队也一样划分相应的内部子团队,一一对接,生成相应的软件。从这个意义上来说,软件开发团队其实应该是和业务部门在同一个部门的。当业务组织发生变化的时候,软件开发部门也应该要有相应的变化,否则就会变成情况1或者情况2的结果了。这就是业务组织架构对开发团队组织架构的影响,顺从这个影响,沟通协作就会很顺。反之则需要大量的资源来纠正这些问题,表现出来就是冲突频繁,内耗严重,每个人都很累,但是成效都不大。

  同样,软件是软件团队的产出物(软件:是指一个可以单独部署运行的完整产出物,组件:软件的组成部分,一般是一个独立开发的单元,不可以单独运行。软件可以由一个或多个组件组成,形成一颗依赖树),对于软件开发团队和软件的关系,也有以下三种情况:

  情况1, 多个软件开发团队开发同一个软件。这时对代码的分支合并的管理要求就非常高,经常会发生互相把对方的代码冲掉的情况,导致严重的线上事故。当这个软件需求比较多的时候,就会导致排队上线的情况,拖慢对业务的响应。

  情况2, 一个软件开发团队开发多个软件。软件开发团队内部很难形成明确的分工,导致一个人会同时修改多个软件,这样就会导致同一个需求,在既可以放在A,也可以放在B的情况下,让多个软件的边界变得非常模糊,形成不恰当的依赖。

  情况3,一个软件开发团队开发一个软件。这样每个软件的职责非常明确,沟通也会比较简单,这是最好的状况。这时形成的还是一颗树。软件和软件之间的关系,反应的就是组织和组织之间的关系,还是一颗树。

  当软件开发团队发生拆分时,软件也需要响应的拆分,否则就会变成情况1。当开发团队发生合并时,这个时候比较难处理,因为软件不一定合并,容易变成情况2。所以一般软件团队开始合并时,往往都是比较乱的。这个时候一定要确保内部的原有分工得以保持。

  在软件开发团队内部,精确到每个人的分工也是一样的道理,一个组件根据内部的分工(参见第八篇)可以分成不同的职责,有负责业务的开发,也有负责技术的开发,这同样就导致了组件的分拆,这里限于篇幅,就不一一展开了。所以从软件团队到人,人到组件,形成的还是一颗树。软件和组件,组件和组件之间,形成的也是一颗树。

  当软件开发进行到一定的程度,每个部门的软件开发团队都会发现很多开发方面共通的东西,因为大家是在同一个公司,大家的东西都是放在同一个网站上的,这时站在整个公司的层面,就会有很多大家都要共同遵守的东西出现。为了避免每个团队都重复发明轮子,这个时候整个公司的软件开发团队也会产生统一的规则和相应的分工:

  同样都面临的技术问题,比方说UED、日志、流量分流、基础框架、运维等,会专门有独立的团队来负责,这样开发团队就分成了专门服务于业务的软件开发团队和专门服务于技术的软件开发团队。

  如果是共享运维团队,那么还需要同样的开发流程保障,也会有独立的团队来服务于各软件开发团队。

  所以业务软件开发团队就变成了这些技术软件开发团队的业务方,也需要相应的组织架构来处理业务软件开发团队提出的需求,也是一个树状结构。这样以技术为导向的同学,就知道自己是处在架构的什么位置,就不会有那么多关于技术和业务关系的困惑。

  对于CEO而言,需要一个CTO来辅助CEO管理软件方面的事务,管理软件开发团队的分工,对于业务软件开发团队所共同面临的问题,建立相应的内部分工,形成软件开发内部团队,配合业务软件开发团队进行工作。这样就形成了如下的组织架构和软件架构:

  以上就是业务组织架构的拆分,如何决定软件开发团队的组织架构,进而决定软件的组织架构。软件开发团队又进行内部的分工,分为业务和技术两类,软件则分解形成了不同的组件,落实到每个研发人员的身上,形成树状的关系。换句话说,软件架构把软件看成虚拟的人实际就是虚拟人的组织架构。架构拆分的原则就来自于业务自身的组织架构,使得软件架构保持和业务组织架构的匹配关系。

  如果不认识到这么深远的影响来源,我们在进行软件开发活动的时候,一定会遇到很多的麻烦:关系错综复杂,难以理清,失去控制。一旦从源头入手整理,一切都清楚了。如果新接手一个团队,搞清楚这些也有利于快速展开工作,并可以在自己的范围之内,尝试调整好这些关系。对于领导而言,调整好这些关系,事半功倍。

  前面我们已经知道,按照业务组织架构,软件分拆为相应的架构。我们就可以把软件当成一个虚拟的人,把软件认识为虚拟人的组织架构。当软件上线后,软件就有了身体,成了一个”真实”的人。当流量进来之后,软件就开始服务于用户的请求。随着流量的增大,软件就会遇到和人同样的问题,一台机器的负载有限,那么就开始增加机器来增加处理能力,或者一个软件开发团队的需求量过多,就开始分拆团队,进而分拆软件,这就是scale out。

  但是当机器达到一定的量之后,仍然会遇到瓶颈,这个时候就会开始考虑对软件进行进一步的分拆。此时就需要分析业务的场景,把该软件所处理的业务分拆成一个树状结构,分散对机器的压力。这个树状结构就是该软件所形成的子树,同时也不能违背之前所述的组织架构拆分原则。

  综上来看,影响软件分拆的动力都是流量的增长,也就是希望单位时间内可以处理更多的业务。一方面流量增长导致了业务本身的拆分,进一步导致了软件的拆分;另一方面,某个软件本身流量的增长也会导致该软件自身的拆分。根本问题都在流量的增长上。从这个角度来看,流量增长是企业都追求的目标,只有更多的流量,业务才能够做大,良好的架构是流量增长的保证。

  很多人就会说这太麻烦了,可不可以把软件架构一步到位地做好?基本上这是不太可能的。一方面在流量不大的时候,做太复杂的拆分会浪费大量时间和不必要的成本;更重要的是因为流量是外在的因素,有经验的人可以做出部分预判,但也没有办法完全预测流量会在哪个地方增长。所以既没必要一步到位,也不可能一步到位。只能结合运维和运营,及时地探测到流量的增长,在流量达到瓶颈之前,根据业务的规律进行合理的拆分,帮助快速的应对增长。同样,我不把这叫做架构演化,因为业务并没有发生变化,只是流量增长,把这叫做软件的长大可能会更合适一点。

  以上所说的是软件拆分背后的原则和原理,也可以说是一个理想情况。现实工作中我们遇到的往往和这个理想情况差距很大。对于我们每一个人来说,理解这些背后的原则,可以让我们在复杂的情况下不再迷茫。如果我们每一个人在自己的能力范围之内,尝试往这个方向努力,真正的为软件开发的环境带来改变,这就善莫大焉了,这篇文章的目的也就达到了。