应对复杂之道:组织架构和技术架构的双解耦


建立软件架构的松耦合的同时,也要建立团队组织架构的松耦合,这两种双解耦才是构建高性能软件组织的关键。通常按功能划分大型团队通常很诱人,我们拥有一个架构师团队,一个开发团队,一个DBA团队,一个测试团队,一个部署团队和一个运营团队,但这不能解决任何扩展问题,没有扩展就没有客户响应,这是团队响应性差的一个原因。
本文讨论了为什么软件和团队不能轻松扩展,我们可以从生物学和互联网上学到的经验,并展示我们如何能够解耦软件和团队以克服扩展问题,讨论是基于作者20年来构建大型软件系统的经验。

软件和软件团队无法扩展的问题
这是一个非常常见的故事,产品的第一个版本,可能由一两个人编写,通常看起来非常简单。它可能只提供有限的功能,但它可以快速编写并满足客户的要求。
客户沟通很好,因为客户通常与开发人员直接沟通。任何缺陷都可以快速修复,并且可以非常轻松地添加新功能。
过了一一段时间响应节奏开始减慢了。
版本2.0需要比预期更长的时间,修复错误和新功能似乎并不那么容易。
对此的自然反应是向团队中添加新的开发人员,但添加到团队中的每个额外人员似乎反而会降低工作效率。
随着软件的老化和复杂性的增长,它似乎在萎缩。
在极端的情况下,公司或组织发现自己运行的软件维护成本非常高,而且几乎不可能改变。有负面的尺度效应。
问题在于你不必为此发生“错误”而负责或内疚,因为几乎所有人说它是软件的“自然”特性。

为什么是这样?有两个原因,与代码相关和与团队相关。代码和团队都没有很好的扩展性。

与代码相关
随着代码库的增长,单个人理解所有代码变得更加困难。这里存在固定的人类认知限制。
一旦团队成长超过五个或更多人,一个人几乎不可能跟上系统所有部分的工作速度;当没有人理解完整的系统时,恐惧就会占上风。
在紧密耦合的大型系统中,很难知道任何重大变化的影响。开发人员学习以最小影响的方式工作和复制,而不是分解共性并创建抽象和概括。
这反映了系统的复杂性,进一步放大了这些消极趋势。
技术债务在增加。
它也会导致令人不愉快和不满意的工作,并鼓励“人才蒸发”,最好的开发人员,那些能够更容易在其他地方找到工作的人,会辞职离开。

与团队相关
团队也没有扩展。随着团队的发展,沟通变得越来越困难。简单的网络公式发挥作用:
c = n(n-1)/ 2 (其中n是人数,c是沟通通道的数量)
随着团队规模的增加,团队的沟通和协调需求几何上升。同级别沟通变得困难。
管理层经常在这个阶段进行干预,并正式建立新的团队和管理结构来组织它们。但无论是正式的还是非正式的,大型组织都难以保持人们的积极性和积极参与。
对于这些缩放病理而言,通常会指责技能匮乏的开发人员和糟糕的管理,但这是不公平的。

规模问题是软件增长和老化的“自然”特性,除非你及早发现问题,否则到拐点时这种情况总会发生,而且很难缓解它。

软件团队不断创建,世界上的软件数量不断增长,而且大多数软件都是小规模的,因此成功且不断发展的产品是由没有大规模软件经验的团队创建的,这种情况是很常见的。

扩展自然教训
我最近阅读了Geoffrey West的优秀书籍Scale。他谈到了生物和社会经济系统中的规模数学。他的论点是,所有大型复杂系统都遵循基本的缩放规律。
作为哺乳动物的我们共享所有哺乳动物的相同细胞类型,骨骼结构,神经和循环系统。然而,鼠标和蓝鲸之间的大小差异大约为10 ^ 7。大自然如何使用相同的基本材料和计划来制造如此巨大不同的生物?
答案似乎是进化已发现分形分支网络。
如果你想想一棵树,这点就可以很明显地看出来,树的每个小部分看起来像一棵小树。
对于我们的哺乳动物循环系统和神经系统也是如此,它们是分支分形网络,其中一小部分肺部或血管看起来像整体的缩小版本。

我们能从大自然中汲取这些想法并将其应用于软件吗?我认为我们可以学到很多重要的经验教训。如果我们可以构建具有看起来像完整系统的较小部分的大型系统,则可能包含影响大多数软件随着其增长和老化的病理。

是否存在可成功扩展多个数量级的现有软件系统?显而易见的答案是互联网,这是一个拥有数百万个节点的全球软件系统。子网确实看起来和工作像整个互联网的较小版本。

解耦软件的密码
将软件组件与较大系统分离的能力是成功扩展的核心技术。互联网基本上是一种解耦的软件架构。这意味着网络上的每个节点,服务或应用程序都具有以下属性:

  • 遵守一个共享的通信协议。
  • 仅通过与其他节点的明确合同共享状态。
  • 不需要实施知识进行沟通。
  • 版本化并独立部署。

因特网是一个节点网络,它通过一组明确定义的协议进行通信。节点仅通过协议共享其状态,一个节点的实现细节不需要与与其通信的节点理解。每个节点都单独进行版本化和部署。各个节点彼此独立地来回发展。
遵守互联网协议是整个系统唯一真正重要的事情。谁构建了每个节点,何时创建或删除它们的版本,它使用的特定技术和平台都与整个互联网无关。这就是解耦软件的含义。

解耦团队的密码
我们可以遵循类似的原则来扩展团队:

  • 每个子团队应该看起来像一个完整的小型软件组织。
  • 团队的内部流程和沟通不应该成为团队之外的关注点。
  • 团队如何实施软件在团队之外不应该是重要的。
  • 团队应该与更广泛的组织就外部问题进行沟通:共同协议,功能,服务水平和资源。

小型软件团队比大型团队更有效率,因此我们应该将大型团队分成更小的团队。来自大自然和互联网的教训是,子团队应该看起来像一个小型的软件组织。多么小?理想情况下,一到五个人。

每个团队看起来像一个小型独立软件组织是很重要的

如果您想避免使用瀑布式项目管理,那么每个团队都需要触及一个功能,通常是以迭代的方式进行。这些职能团队之间的沟通边界成为有效和及时交付的主要障碍。因为团队之间没有彼此脱钩,他们需要共享重要的内部细节才能一起工作。
此外,不同团队的利益也不一致:开发团队通常会因功能交付而有奖金;质量测试团队则因软件的稳定性支持才能获得奖励,这些不同的利益可能导致冲突和交付不良。

相反,我们应该通过分离的软件服务来组织团队,这些服务支持业务功能或逻辑组功能。每个子团队都应该设计,编码,测试,部署和支持他们自己的软件。

由于小团队需要分担这些角色,因此个别团队成员更有可能成为通才而不是专家,他们应该关注尽可能多的流程自动化:自动化测试,部署和监控,团队应该选择自己的工具并自己决定如何构建他们的系统。

虽然系统用于沟通的组织协议必须在组织公司级别决定,但用于实现服务的工具的选择应该委派给团队,这非常符合DevOps软件组织模型。

团队拥有的自治水平反映了与更广泛的组织脱钩的程度。理想情况下,组织应关注团队提供的功能,最终是业务价值,以及团队资源的成本。

软件架构师的角色在这种组织方式中很重要。他们不应该专注于团队使用的特定工具和技术,或者微观管理服务的内部架构,而应该专注于各种服务之间的协议和交互以及整个系统的健康状况。

反Conway康威定理:软件公司应该对目标架构进行建模
解耦软件和解耦团队如何协调?康威定律指出:

“设计系统的组织......会对所提供设计有限制,这些设计结果其实是这些组织的沟通结构的样板复制。”

这是基于以下观察:软件系统架构将反映创建它的组织的团队结构。

我们可以通过”反者道之动“来“破解”康威定律:组织我们的团队以反映我们所需的架构。应该将分离团队与分离软件组件保持一致,这应该是一对一的关系吗?
我认为这是理想的,尽管对于一个小团队来说,提供几种解耦软件服务似乎没什么问题,团队的缩放拐点大于软件的缩放拐点,这样的组织形式才是有效的。
但是,即使某些人共享同一个团队,重要的是软件组件应该与他们自己的版本和部署故事保持隔离。
如果团队变得太大,我们希望能够分散团队,并且能够将各种服务交给不同的团队将是一个主要的好处。如果服务紧密耦合或团队之间共享流程、版本控制或部署,我们就无法做到这一点。
我们应该避免让多个团队在相同的组件上工作,这是一种反模式,并且在某些方面比单个大型团队在超大单个代码库上工作更糟糕,因为团队之间的沟通障碍导致更糟糕的缺乏感觉所有权和控制权。


建立了松耦合的软件的松耦合团队之间的沟通要求被最小化。
再次以互联网为例,如果流程简单且文档充足,通常可以使用其他公司提供的API而无需任何直接沟通。沟通不应该要求对团队内部的软件过程或实现进行任何讨论,而是应该提供有关提供功能,服务级别和资源的进行沟通。

构建分离软件的分离式软件团队组织应该比其他选择更容易管理。较大的组织应该专注于为团队提供明确的功能和服务水平的目标和要求。资源需求应来自团队,但组织可以使用它来衡量投资回报。

建立解耦软件的解耦团队
松耦合软件和团队是构建高性能软件组织的关键。
我的轶事经验支持这种观点,我曾经在各种组织或公司中工作,在这些组织中,团队通过软件功能或软件层进行隔离,甚至是他们被客户隔离的地方。
我还在单个代码库上的混乱大型团队中工作过。所有这些都受到上面讨论的缩放问题的困扰。最快乐的体验始终是我的团队是一个完整的软件单元,独立构建,测试和部署分离的服务。但是你不必依赖我的轶事证据,“ 加速:精益软件和DevOps的科学:构建和扩展高性能技术组织 ”一书中有调查数据来支持这种观点。