微服务架构的理论基础 - 康威定律

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 可能出乎很多人意料之外的一个事实是,微服务很多核心理念其实在半个世纪前的一篇文章中就被阐述过了,而且这篇文章中的很多论点在软件开发飞速发展的这半个世纪中竟然一再被验证,这就是康威定律。前段时间看了Mike Amundsen 《远距离条件下的康威定律——分布式世界中实现团队构建》在InfoQ上的一个分

概述

关于微服务的介绍,可以参考微服务那点事

微服务是最近非常火热的新概念,大家都在追,也都觉得很对,但是似乎没有很充足的理论基础说明这是正确的,给人的感觉是 不明觉厉 。前段时间看了Mike Amundsen 《远距离条件下的康威定律——分布式世界中实现团队构建》(是Design RESTful API的作者)在InfoQ上的一个分享,觉得很有帮助,结合自己的一些思考,整理了该演讲的内容。

可能出乎很多人意料之外的一个事实是,微服务很多核心理念其实在半个世纪前的一篇文章中就被阐述过了,而且这篇文章中的很多论点在软件开发飞速发展的这半个世纪中竟然一再被验证,这就是康威定律(Conway's Law)

screenshotscreenshot

在康威的这篇文章中,最有名的一句话就是:

Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. - Melvin Conway(1967)

中文直译大概的意思就是:设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。看看下面的图片(来源于互联网,侵删),再想想Apple的产品、微软的产品设计,就能形象生动的理解这句话。
screenshot

用通俗的说法就是:组织形式等同系统设计。

这里的系统按原作者的意思并不局限于软件系统。据说这篇文章最初投的哈佛商业评论,结果程序员屌丝的文章不入商业人士的法眼,无情被拒,康威就投到了一个编程相关的杂志,所以被误解为是针对软件开发的。最初这篇文章显然不敢自称定律(law),只是描述了作者自己的发现和总结。后来,在Brooks Law著名的人月神话中,引用这个论点,并将其“吹捧”成了现在我们熟知“康威定律”。

康威定律详细介绍

Mike从他的角度归纳这篇论文中的其他一些核心观点,如下:

  • 第一定律

    • Communication dictates design
    • 组织沟通方式会通过系统设计表达出来
  • 第二定律

    • There is never enough time to do something right, but there is always enough time to do it over
    • 时间再多一件事情也不可能做的完美,但总有时间做完一件事情
  • 第三定律

    • There is a homomorphism from the linear graph of a system to the linear graph of its design organization
    • 线型系统和线型组织架构间有潜在的异质同态特性
  • 第四定律

    • The structures of large systems tend to disintegrate during development, qualitatively more so than with small systems
    • 大的系统组织总是比小系统更倾向于分解

人是复杂社会动物

  • 第一定律

    • Communication dictates design
    • 组织沟通方式决定系统设计

组织的沟通和系统设计之间的紧密联系,在很多别的领域有类似的阐述。对于复杂的系统,聊设计就离不开聊人与人的沟通,解决好人与人的沟通问题,才能有一个好的系统设计。相信几乎每个程序员都读过的《人月神话》(1975年,感觉都是老古董了,经典的就是经得起时间考验)里面许多观点都和这句话有异曲同工之妙。

screenshotscreenshot

比如《人月神话》中最著名的一句话就是

Adding manpower to a late software project makes it later --Fred Brooks, (1975)

Boss们都听到了吗?为了赶进度加程序员就像用水去灭油锅里的火一样(无奈大家还是前赴后继)。

为什么?人月神话也给出了很简洁的答案:沟通成本 = n(n-1)/2,沟通成本随着项目或者组织的人员增加呈指数级增长。是的,项目管理这个算法的复杂度是O(n^2)。举个例子

  • 5个人的项目组,需要沟通的渠道是 5*(5–1)/2 = 10
  • 15个人的项目组,需要沟通的渠道是15*(15–1)/2 = 105
  • 50个人的项目组,需要沟通的渠道是50*(50–1)/2 = 1,225
  • 150个人的项目组,需要沟通的渠道是150*(150–1)/2 = 11,175

所以知道为什么互联网创业公司都这么小了吧,必须小啊,不然等CEO和所有人讲一遍创业的想法后,风投的钱都烧完了。

Mike还举了一个非常有意思的理论,叫“Dunbar Number”,这是一个叫Dunbar(废话)生物学家在1992年最早提出来的。最初,他发现灵长类的大脑容量和其对应的族群大小有一定关联,进而推断出人类的大脑能维系的关系的一些有趣估计。举例来说

  • 亲密(intimate)朋友: 5
  • 信任(trusted)朋友: 15
  • 酒肉(close)朋友: 35
  • 照面(casual)朋友: 150

screenshot

是不是和上面的沟通成本的数字很貌似有关联?是的,我们的大脑智力只能支持我们维系这么多的关系。(大家都知道这不是程序猿擅长的领域,在开发团队里,这个值应该更小,估计和猿差不多 -_-凸 )

沟通的问题,会带来系统设计的问题,进而影响整个系统的开发效率和最终产品结果。

一口气吃不成胖子,先搞定能搞定的

  • 第二定律:

    • There is never enough time to do something right, but there is always enough time to do it over
    • 时间再多一件事情也不可能做的完美,但总有时间做完一件事情

Eric Hollnagel是敏捷开发社区的泰斗之一,在他《Efficiency-Effectiveness Trade Offs》 一书中解释了类似的论点。

Problem too complicated? Ignore details.
Not enough resources?Give up features.

      --Eric Hollnagel (2009)

screenshotscreenshot

系统越做越复杂,功能越来越多,外部市场的竞争越来越剧烈,投资人的期待越来越高。但人的智力是有上限的,即使再牛逼的人,融到钱再多也不一定招到足够多合适的人。对于一个巨复杂的系统,我们永远无法考虑周全。Eric认为,这个时候最好的解决办法竟然是——“破罐子破摔”。

其实我们在日常开发中也经常碰到。产品经理的需求太复杂了?适当忽略一些细节,先抓主线。产品经理的需求太多了?放弃一些功能。

据说Eric被一家航空公司请去做安全咨询顾问,复杂保证飞机飞行系统的稳定性和安全性。Eric认为做到安全有两种方式:

  • 常规的安全指的是尽可能多的发现并消除错误的部分,达到绝对安全,这是理想。
  • 另一种则是弹性安全,即使发生错误,只要及时恢复,也能正常工作,这是现实。

对于飞机这样的复杂系统,再牛逼的人也无法考虑到漏洞的方方面面,所以Eric建议放弃打造完美系统的想法,而是通过不断的试飞,发现问题,确保问题发生时,系统能自动复原即可,而不追求飞行系统的绝对正确和安全。

下面的图很好的解释了这个过程:
screenshot
听着很耳熟不是吗?这不就是 持续集成 和敏捷开发吗?的确就是。

另一方面,这和互联网公司维护的分布式系统的弹性设计也是一个道理。对于一个分布式系统,我们几乎永远不可能找到并修复所有的bug,单元测试覆盖1000%也没有用,错误流淌在分布式系统的血液里。解决方法不是消灭这些问题,而是容忍这些问题,在问题发生时,能自动回复,微服务组成的系统,每一个微服务都可能挂掉,这是常态,我们只有有足够的冗余和备份即可。即所谓的 弹性设计(Resilience) 或者叫高可用设计(High Availability)。

种瓜得瓜,做独立自治的字系统减少沟通成本

  • 第三定律

    • There is a homomorphism from the linear graph of a system to the linear graph of its design organization
    • 线型系统和线型组织架构间有潜在的异质同态特性

screenshot

这是康威第一定律组织和设计间内在关系的一个具体应用。更直白的说,你想要什么样的系统,就搭建什么样的团队。如果你的团队分成前端团队,Java后台开发团队,DBA团队,运维团队,你的系统就会长成下面的样子:
screenshot

相反,如果你的系统是按照业务边界划分的,大家按照一个业务目标去把自己的模块做出小系统,小产品的话,你的大系统就会长成下面的样子,即微服务的架构
screenshot

微服务的理念团队间应该是 inter-operate, not integrate 。inter-operate是定义好系统的边界和接口,在一个团队内全栈,让团队自治,原因就是因为如果团队按照这样的方式组建,将沟通的成本维持在系统内部,每个子系统就会更加内聚,彼此的依赖耦合能变弱,跨系统的沟通成本也就能降低。

合久必分,分而治之

  • 第四定律

    • The structures of large systems tend to disintegrate during development, qualitatively more so than with small systems
    • 大的系统组织总是比小系统更倾向于分解

前面说了,人是复杂的社会动物,人与人的通过非常复杂。但是当我们面对复杂系统时,又往往只能通过增加人力来解决。这时,我们的组织一般是如何解决这个沟通问题的呢?Divide and conquer,分而治之。大家看看自己的公司的组织,是不是一个一线经理一般都是管理15个人以下的?二线经理再管理更少的一线?三线再管理更少的,以此类推。(这里完全没有暗示开发经理比程序猿更难管理)

所以,一个大的组织因为沟通成本/管理问题,总为被拆分成一个个小团队。

  • 创业的想法太好了,反正风投钱多,多招点程序猿
  • 人多管不过来啊,找几个经理帮我管,我管经理
  • 最后, 康威定律 告诉我们组织沟通的方式会在系统设计上有所表达,每个经理都被赋予一定的职责去做大系统的某一小部分,他们和大系统便有了沟通的边界,所以大的系统也会因此被拆分成一个个小团队负责的小系统(微服务是一种好的模式)

康威定律如何解释微服务的合理性

了解了康威定律是什么,再来看看他如何在半个世纪前就奠定了微服务架构的理论基础。

  • 人与人的沟通是非常复杂的,一个人的沟通精力是有限的,所以当问题太复杂需要很多人解决的时候,我们需要做拆分组织来达成对沟通效率的管理
  • 组织内人与人的沟通方式决定了他们参与的系统设计,管理者可以通过不同的拆分方式带来不同的团队间沟通方式,从而影响系统设计
  • 如果子系统是内聚的,和外部的沟通边界是明确的,能降低沟通成本,对应的设计也会更合理高效
  • 复杂的系统需要通过容错弹性的方式持续优化,不要指望一个大而全的设计或架构,好的架构和设计都是慢慢迭代出来的

带来的具体的实践建议是:

  • 我们要用一切手段提升沟通效率,比如slack,github,wiki。能2个人讲清楚的事情,就不要拉更多人,每个人每个系统都有明确的分工,出了问题知道马上找谁,避免踢皮球的问题。
  • 通过MVP的方式来设计系统,通过不断的迭代来验证优化,系统应该是弹性设计的。
  • 你想要什么样的系统设计,就架构什么样的团队,能扁平化就扁平化。最好按业务来划分团队,这样能让团队自然的自治内聚,明确的业务边界会减少和外部的沟通成本,每个小团队都对自己的模块的整个生命周期负责,没有边界不清,没有无效的扯皮,inter-operate, not integrate。
  • 做小而美的团队,人多会带来沟通的成本,让效率下降。亚马逊的Bezos有个逗趣的比喻,如果2个披萨不够一个团队吃的,那么这个团队就太大了。事实上一般一个互联网公司小产品的团队差不多就是7,8人左右(包含前后端测试交互用研等,可能身兼数职)。

再对应下衡量微服务的标准,我们很容易会发现他们之间的密切关系:

  • 分布式服务组成的系统
  • 按照业务而不是技术来划分组织
  • 做有生命的产品而不是项目
  • Smart endpoints and dumb pipes(我的理解是强服务个体和弱通信)
  • 自动化运维(DevOps)
  • 容错
  • 快速演化

参考资料

目录
相关文章
|
10天前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
10天前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
13天前
|
JSON 监控 安全
探索微服务架构中的API网关模式
【9月更文挑战第22天】在微服务架构的海洋中,API网关如同一位智慧的守门人,不仅管理着服务的进出,还维护着整个系统的秩序。本文将带你一探究竟,看看这位守门人是如何工作的,以及它为何成为现代云原生应用不可或缺的一部分。从流量控制到安全防护,再到服务聚合,我们将一起解锁API网关的秘密。
|
22天前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
29 3
|
27天前
|
监控 负载均衡 应用服务中间件
探索微服务架构下的API网关设计与实践
在数字化浪潮中,微服务架构以其灵活性和可扩展性成为企业IT架构的宠儿。本文将深入浅出地介绍微服务架构下API网关的关键作用,探讨其设计原则与实践要点,旨在帮助读者更好地理解和应用API网关,优化微服务间的通信效率和安全性,实现服务的高可用性和伸缩性。
38 3
|
1月前
|
存储 Java Maven
从零到微服务专家:用Micronaut框架轻松构建未来架构
【9月更文挑战第5天】在现代软件开发中,微服务架构因提升应用的可伸缩性和灵活性而广受欢迎。Micronaut 是一个轻量级的 Java 框架,适合构建微服务。本文介绍如何从零开始使用 Micronaut 搭建微服务架构,包括设置开发环境、创建 Maven 项目并添加 Micronaut 依赖,编写主类启动应用,以及添加控制器处理 HTTP 请求。通过示例代码展示如何实现简单的 “Hello, World!” 功能,并介绍如何通过添加更多依赖来扩展应用功能,如数据访问、验证和安全性等。Micronaut 的强大和灵活性使你能够快速构建复杂的微服务系统。
61 5
|
9天前
|
Kubernetes Go Docker
掌握微服务架构:从Go到容器化的旅程
摘要,通常简短概述文章内容,要求精炼。在本文中,我们将打破常规,采用一种故事化叙述的摘要,旨在激发读者的好奇心和探究欲: “从宁静的海滨小城出发,我们踏上了一场技术探险之旅,探索微服务架构的奥秘。我们将学习如何用Go编写微服务,以及如何通过Docker和Kubernetes将它们打包进小巧的容器中。在这场旅程中,我们将遇到挑战、收获知识,最终实现应用的快速部署与可扩展性。”
|
11天前
|
Cloud Native Java 对象存储
揭秘微服务架构之争:Spring Cloud与Netflix OSS巅峰对决,谁将称霸弹性云原生时代?
近年来,微服务架构成为企业应用的主流设计模式。本文对比了两大热门框架Spring Cloud和Netflix OSS,探讨其在构建弹性微服务方面的表现。Spring Cloud依托Spring Boot,提供全面的微服务解决方案,包括服务注册、配置管理和负载均衡等。Netflix OSS则由一系列可独立或组合使用的组件构成,如Eureka、Hystrix等。两者相比,Spring Cloud更易集成且功能完善,而Netflix OSS则需自行整合组件,但灵活性更高。实际上,两者也可结合使用以发挥各自优势。通过对两者的对比分析,希望为企业在微服务架构选型上提供参考。
30 0
|
19天前
|
缓存 负载均衡 数据管理
深入探索微服务架构的核心要素与实践策略在当今软件开发领域,微服务架构以其独特的优势和灵活性,已成为众多企业和开发者的首选。本文将深入探讨微服务架构的核心要素,包括服务拆分、通信机制、数据管理等,并结合实际案例分析其在不同场景下的应用策略,旨在为读者提供一套全面、深入的微服务架构实践指南。**
**微服务架构作为软件开发领域的热门话题,正引领着一场技术革新。本文从微服务架构的核心要素出发,详细阐述了服务拆分的原则与方法、通信机制的选择与优化、数据管理的策略与挑战等内容。同时,结合具体案例,分析了微服务架构在不同场景下的应用策略,为读者提供了实用的指导和建议。
|
2月前
|
数据库 Java 数据库连接
Hibernate 实体监听器竟如魔法精灵,在 CRUD 操作中掀起自动化风暴!
【8月更文挑战第31天】在软件开发中,效率与自动化至关重要。Hibernate 通过其强大的持久化框架提供了实体监听器这一利器,自动处理 CRUD 操作中的重复任务,如生成唯一标识符、记录更新时间和执行清理操作,从而大幅提升开发效率并减少错误。下面通过示例代码展示了如何定义监听器类,并在实体类中使用 `@EntityListeners` 注解来指定监听器,实现自动化任务。这不仅简化了开发流程,还能根据具体需求灵活应用,满足各种业务场景。
32 0
下一篇
无影云桌面