<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>从分层架构到微服务架构 on 元闰子的邀请</title>
    <link>https://yrunz.com/tags/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84/</link>
    <description>Recent content in 从分层架构到微服务架构 on 元闰子的邀请</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 08 Apr 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://yrunz.com/tags/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从分层架构到微服务架构（五）之服务化架构</title>
      <link>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%BA%94%E4%B9%8B%E6%9C%8D%E5%8A%A1%E5%8C%96%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Fri, 08 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%BA%94%E4%B9%8B%E6%9C%8D%E5%8A%A1%E5%8C%96%E6%9E%B6%E6%9E%84/</guid>
      <description>《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章，这里不会事无巨细地介绍所有的细节，而是会挑选其中关键内容，更多详情请阅读原书。
往期精彩：
 从分层架构到微服务架构（一） 从分层架构到微服务架构（二）之分层架构 从分层架构到微服务架构（三）之管道架构 从分层架构到微服务架构（四）之微内核架构   前言 从本文开始，我们进入了《从分层架构到微服务架构》系列中分布式架构的介绍，本文要介绍的是服务化架构（Service-Based Architecture，SBA）。
SBA 可以看成是单体架构和微服务架构之间的一个折中方案，它也是按照业务领域进行服务划分，但服务划分的粒度相比微服务要更粗。SBA 与微服务架构一大不同是，它允许各个服务间共享同一个数据库实例，这也使得 SBA 在架构上既有单体架构的特点，也有分布式架构的特点，显得更加的灵活。因此，从单体架构演进到 SBA，会比直接演进到微服务架构更加容易。
架构视图 基础视图 SBA 的基础架构视图分成 3 部分：
 User Interface，作为系统的接入口，接收客户端的请求，并转发到业务服务。。 Domain Services，业务服务按照领域进行划分，分开部署、业务独立。 Database，服务间共享的数据库实例，因为数据库实例只有一个，所以可以支持 ACID 事务。  使用 SBA 的系统通常只会划分 4 ～ 12 个服务，避免产生过多的数据库连接。服务数量不多，也决定了 SBA 中的服务相比微服务架构中的服务有着更粗的粒度。User Interface 与服务间通过远程通信协议来完成业务往来，常见的通信方式有REST、RPC、消息队列等。需要注意的是，SBA 是不允许服务间通信的，这与微服务架构有着本质的区别。
大多数情况下，SBA 中的服务只有一个或者少量实例，与微服务动辄成百上千个实例有着很大的区别。主要是因为 SBA 服务粒度更粗，无法做到像微服务那样精准的按需扩容，扩容太多反而会导致资源的浪费。
SBA 的另一大特点是允许所有服务共享同一数据库实例，使得它能够直接将传统单体架构的那一套 SQL 查询逻辑、ACID 事务搬过来，让架构的演进更加的平滑。不过，共享数据也会带来一些问题，比如数据模型变更的影响范围更大，后面会在“**数据拆分”**一节详细讲述。
拆分 User Interface 在大型系统中，单一的 User Interface 可能导致代码耦合、性能瓶颈等问题，这时候我们可以进一步对它进行拆分。拆分的方法可以是基于业务领域的拆分，业务相关的几个服务使用同一个 User Interface；或者基于服务的拆分，为每个服务都配备一个 User Interface。
拆分 Database 类似地，我们也可以对数据库进行拆分，可以拆分成几个服务共享一个实例；也可以像微服务架构中那样，每个服务独享一个实例。数据库拆分的原则就是：确保数据是解耦的，不会被其他服务所依赖，避免出现跨库查询或服务间通信。</description>
    </item>
    
    <item>
      <title>从分层架构到微服务架构（四）之微内核架构</title>
      <link>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E5%9B%9B%E4%B9%8B%E5%BE%AE%E5%86%85%E6%A0%B8%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Fri, 23 Apr 2021 00:00:00 +0000</pubDate>
      
      <guid>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E5%9B%9B%E4%B9%8B%E5%BE%AE%E5%86%85%E6%A0%B8%E6%9E%B6%E6%9E%84/</guid>
      <description>《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章，这里不会事无巨细地介绍所有的细节，而是会挑选其中关键内容，更多详情请阅读原书。
往期精彩：
 从分层架构到微服务架构（一） 从分层架构到微服务架构（二）之分层架构 从分层架构到微服务架构（三）之管道架构   前言 微内核架构（Microkernel Architecture），也被称为插件式架构（plug-in architecture），作为一个在几十年前就被创建出来的架构模式，它如今仍然被广泛应用在各个领域中。比如在Web浏览器领域，谷歌的Chrome浏览器之所以被认为功能强大，一个很重要的原因是它有着丰富的插件类型；在开发工具领域，微软的VS Code初始安装后还只是个简单的文本编辑器，但用户可以安装各种插件，从而让它摇身一变成为功能强大的IDE。
Chrome和VS Code都是微内核架构的典型应用例子，它们提供一个具备最基础能力的核心系统，并定义好插件的开发接口。至于需要开发或安装哪种类型的插件，则完全由普通开发者和用户决定，这样的设计让系统具备了极强的可定制化和可扩展能力。
架构视图 微内核架构由以下两部分组成：核心系统（core system）和插件（plug-in component），将应用系统的业务逻辑拆分成核心系统和插件，能够提供很好的可扩展性和灵活性，极大地方便了后续需求的新增和修改。
核心系统 核心系统通常只需提供能够支撑整个系统正常运行的基本功能，比如前文所举的VS Code例子，用户初始安装的是VS Code的核心系统，它只是一个提供了打开文件、编辑文件内容和保存文件等基本功能的文本编辑器，其他的扩展功能（如语法检查）都是通过安装插件集成的。将复杂的业务逻辑从核心系统中剥离出来，并通过插件实现，能够提升系统的可扩展性和可维护性。同时，因为复杂的功能都成了互不干扰的插件，系统的可测性也得到了提高。
考虑现在需要实现一个电子设备回收系统，在回收之前，每种型号的手机设备的回收流程都不一样，那么我们可以这样去实现：
public void assessDevice(String deviceID) { if (deviceID.equals(&amp;#34;iPhone6s&amp;#34;)) { assessiPhone6s(); } else if (deviceID.equals(&amp;#34;iPad1&amp;#34;)) assessiPad1(); } else if (deviceID.equals(&amp;#34;Galaxy5&amp;#34;)) assessGalaxy5(); } else ... ... } } 如果我们把assessDevice看成是核心系统，那么后面每次新增一个型号的手机，都需要新增一个if分支，也即对核心系统进行了改动。这样的设计会导致核心系统非常地脆弱，正所谓改的越多，出问题的概率也越大。
比起这种将所有的可定制业务逻辑放在核心系统上的设计，更好的应该是将它们实现为插件的形式，这样不仅每个设备回收逻辑都解耦了，还提供了强大的可扩展性：添加一个新的回收设备类型，只需新增一种插件即可，核心系统无需变动。
public void assessDevice(String deviceID) { String plugin = pluginRegistry.get(deviceID); DevicePlugin devicePlugin = (DevicePlugin)constructor.newInstance(); DevicePlugin.assess(); } 微内核架构在实现时通常都结合了其他架构模式，这主要体现在核心系统的设计上，比如根据具体的业务特点，我们可以将核心系统设计成technically partitioned的分层架构，或者是domain partitioned的模块化架构。</description>
    </item>
    
    <item>
      <title>从分层架构到微服务架构（三）之管道架构</title>
      <link>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%B8%89%E4%B9%8B%E7%AE%A1%E9%81%93%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Mon, 05 Apr 2021 00:00:00 +0000</pubDate>
      
      <guid>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%B8%89%E4%B9%8B%E7%AE%A1%E9%81%93%E6%9E%B6%E6%9E%84/</guid>
      <description>《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章，这里不会事无巨细地介绍所有的细节，而是会挑选其中关键内容，更多详情请阅读原书。
往期精彩：
 从分层架构到微服务架构（一） 从分层架构到微服务架构（二）之分层架构   前言 管道架构（Pipeline Architecture），通常也被称为管道-过滤器架构（Pipes and Filter Architecture），是最常用的架构模式之一。大部分软件工程师都是通过Unix终端初次接触到该架构模式，Unix终端的Shell语言，对管道-过滤器有着原生的支持。
比如，现在需要实现这样的一个功能：读取一个文本文件的内容，找到使用频率最高的5个单词，并按照使用频率的大小顺序打印出单词及其使用频率。
那么，使用Shell可以这样来实现：
cat content.txt | # step1: 读取文件内容 tr -cs A-Za-z &amp;#39;\n&amp;#39; | # step2: 将单词按行输出 tr A-Z a-z | # step3: 将所有单词转换为 sort | # step4: 对单词进行排序 uniq -c | # step5: 计算出单词的频率 sort -rn | # step6: 按照频率对单词进行排序 head -n 5 # step7: 获取排序前5的单词 # 输出结果示例： 4 to 4 and 3 the 3 networks 3 linux 这段Shell代码就是一个简单的管道架构实现，其中|表示管道pipe，每一个step就相当于一个过滤器filter。每个filter都将上一个filter的输出结果作为输入数据，对数据进行处理后再将结果输出到管道中。</description>
    </item>
    
    <item>
      <title>从分层架构到微服务架构（二）之分层架构</title>
      <link>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%BA%8C%E4%B9%8B%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Sat, 30 Jan 2021 00:00:00 +0000</pubDate>
      
      <guid>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%BA%8C%E4%B9%8B%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84/</guid>
      <description>《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章，这里不会事无巨细地介绍所有的细节，而是会挑选其中关键内容，更多详情请阅读原书。
往期精彩：
 从分层架构到微服务架构（一）   前言 软件刚出现的时候，还是大型计算机的年代，一个软件系统一般都只会运行在一台机器上。随着软硬件技术的革新，计算机体积和成本逐渐变小，此时工程师们发现一个软件系统只运行在单台机器上会存在各种瓶颈。如果将系统按照功能划分成前端和后端，分别部署在两台服务器上，问题得到了缓解，于是便有了Client/Server架构的出现。
随后，个人电脑的兴起带动了众多富桌面应用（rich desktop application）的出现，它们基于操作系统上的user interface开发，数据则是存储在单独部署的database server上，通过标准的网络协议进行数据通信。这种Desktop + Database Server的架构和C/S架构一样，同属两层架构（two-tier architecture）。
随着90年代互联网的迅速崛起，Browser + Web Server + Database Server的组合也渐渐风靡。Browser为表现层，提供用户交互界面；Web Server为业务层，处理具体的业务逻辑；Database Server为数据层，存储系统数据。三个层次各司其职，这也是大家最熟悉的三层架构（three-tier architecture）。
上述的几种架构模式都属于分层架构（layered architecture）的范畴，分层架构并没有限定一定得有多少个层次，层次的数量可以根据应用场景灵活控制，因此也被称为n-tier architecture。它结构简单，基于此架构进行系统开发成本也很低（很多公司在组织结构上划分为前端工程师、后端工程师、DBA，根据康威定律，这天然就具备了分层架构开发的良好条件），因此它在业界备受欢迎。如果你的团队还不确定选择什么样的架构，又或者为了践行敏捷宣言中的“just starts coding“，那么分层架构会是一个不错的选择。
架构视图 在分层架构中，组件根据功能被划分在不同的层次上，虽然层次的数量和类型并没有被限制，但大多数的分层架构都由以下4层组成：表现层（presentation）、业务层（business）、持久层（persistence）和数据层（database），如下图所示。在一些简单的系统中，持久层的逻辑（如SQL）被嵌入到业务层中，形成了经典的三层架构；而在一些复杂的系统中，也会根据具体的业务划分为五层甚至更多的层次。
前文所述的表现层等4个层次都是逻辑的划分方法，在实际部署时，一般会有下图所示的几种部署形态。形态1中，表现层、业务层和持久层为一个部署单元，而数据层则单独部署，具体表现为一个独立部署的数据库或文件系统；形态2中，表现层被分离出单独部署，业务层和持久层组成一个部署单元，数据层依旧是单独部署的数据库或文件系统；形态3中，包括数据层在内的4层全都在同一个部署单元内，常见于业务简单的系统，它们往往使用的是嵌入式数据库或内存数据库。
分层架构中的每一层都扮演着各自的角色，比如表现层负责处理所有的用户请求和浏览器交互，而业务层则负责执行每次请求下的特定业务逻辑；表现层无需担心从哪里获取用户数据，它只需要将数据以特定的格式在浏览器上显示即可。同样地，业务层也无需关心用户数据从何而来以及如何呈现，它只需从持久层中取出数据，执行特定的业务逻辑（比如聚合数据），然后将结果返回给表现层。
每一层都是特定行为的抽象，这样的职责划分，使得组织能够快速高效地创建出责任模型，围绕各层打造开发团队。
层间隔离 分层架构中的每一层可以是封闭的或者开放的，封闭意味着当一个请求自顶向下在层间传递时，它不能跳过任意的一层。比如，当表现层接收到请求之后，它必须先后经过业务层和持久层才能到达数据层，如下图所示。
对于简单的数据获取类请求，如果让表现层能够直接访问数据层获取数据，无疑是最简单高效的。也即是让业务层和持久层变成开放状态，允许请求在层间传递时跳过此层。那么，究竟是封闭好，还是开放好呢？要解答这个问题，就要回到层间隔离的出发点上。
所谓的层间隔离，旨在降低一个层次上的变化对其他层次的组件的影响，简单来说，就是每个层次对其他层次的功能知道的越少越好。为了达到层间隔离的目的，就需要将每个层次置为封闭的状态。假设表现层能够直接访问持久层，那么持久层的变化将会直接影响到业务层和表现层，这加剧了层间的耦合，导致系统变化的代价高昂。
层间隔离可以降低层次变化对系统的影响，凡事没有绝对，在某些的场景，将特定的层次置为开放的状态也不失为一件好事。考虑以下例子，业务层中存在着一些共享组件承载着业务层公共的功能（比如日志类、审计类、日期和字符串工具类等）。现在有一项架构决策要求表现层不能直接访问这些共享组件，但矛盾的是，原则上表现层是可以直接访问业务层的，这种需要违反原则的决策将会很难落地。
一种解决方法是，新增一个服务层，该层包含了业务层的这些共享组件。因为业务层是关闭的状态，故表现层也就不能访问到这些共享组件了。然而，新增的服务层必须置为开放状态，否则业务层将无法直接访问持久层。新增一个服务层并置为开放状态，这样既落地了架构决策，也不会影响到原有的功能，一举两得。
注意事项 在使用分层架构时，需要注意以下两点：
1、做好模块的划分
为分层架构做好模块划分主要是为后续的架构演进做好准备，比如在业务复杂到一定程度后演进为微服务架构时，各个模块可以很自然地演进为微服务。为此，应该避免出现类的继承层次过深的现象，这会导致代码严重的耦合，不利于后续的架构演进。
2、避免掉进sinkhole反模式的陷阱
所谓sinkhole反模式指的是请求只是简单地路过各个层次，并没有做一些业务处理。
比如，表现层接收到一个获取基本用户数据（姓名、地址等）的请求后将它传递到业务层；然而，业务层并没有做任何的业务处理，直接将请求传递到持久层；持久层也仅仅是构造了一个简单的SQL语句，向数据层查询用户数据；最后，数据按照原路返回到表现层，中途没有经过任何的数据汇聚、转换等操作。
sinkhole反模式会导致很多不必要的对象实例化开销，从而增大了系统的内存消耗，并且影响了性能。
然而，一个系统多多少少都会存在一些sinkhole反模式场景，要判断一个系统是否已经彻底掉进sinkhole反模式的陷阱，主要还是看这类业务请求所占的百分比。根据20-80法则，当系统中有超过80%的业务请求是sinkhole类请求时，表示系统已经掉进sinkhole反模式的陷阱，这从侧面也说明该系统已经不再适合分层架构，是时候考虑架构演进了。
架构评分 从综合得分上看，分层架构的Overall cost和Simplicity得分很高，这很大程度上得益于分层架构本身是单体架构，少了很多分布式系统才有的复杂性。但这样导致Deployability得分很低，因为3行代码的改动就足以造成整个系统的重新部署。Testability得分不高也是这个原因，整系统的重新上线通常都需要将测试用例全部执行一遍，多了不少额外的工作量。
Elasticity、Fault tolerance、Scalability这些都是单体架构天然的劣势，自然地，分层架构在这些方面得分都很低。另外，sinkhole反模式的存在也拉低了分层架构在Performance上的得分。
总结 分层架构简单而高效，业界已经有很多成熟的应用，对那些项目刚刚起步，架构师们还没想好要采用哪种架构模式的系统而言，这是非常适合的。在实现分层架构时，我们需要合理地设置各个层次的封闭或开放状态，做好层间隔离，同时也要避免掉进sinkhole反模式陷阱。随着业务的不断扩张，分层架构在可维护性、可测试性、可扩展性等上的短板也会逐步被放大，此时就需要考虑往其他架构模式演进了。
每种架构模式都有其合适的应用场景，只有熟悉常用的几种架构模式，才能设计出更好的软件系统。下一篇文章，我们将继续介绍管道架构。</description>
    </item>
    
    <item>
      <title>从分层架构到微服务架构（一）</title>
      <link>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%B8%80/</link>
      <pubDate>Sat, 23 Jan 2021 00:00:00 +0000</pubDate>
      
      <guid>https://yrunz.com/p/%E4%BB%8E%E5%88%86%E5%B1%82%E6%9E%B6%E6%9E%84%E5%88%B0%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E4%B8%80/</guid>
      <description>《从分层架构到微服务架构》是一系列介绍《Fundamentals of Software Architecture》中提到的8种架构模式的文章，这里不会事无巨细地介绍所有的细节，而是会挑选其中关键内容，更多详情请阅读原书。
 前言 谈到软件系统设计的方法论，在代码层面，有我们熟悉的23种设计模式（design pattern），对应到架构层面，则有所谓的架构模式（architecture pattern）。它们分别从微观和宏观的角度指导着我们设计出良好的软件系统，因此，作为一个软件工程师，我们不仅要熟悉设计模式，对常见的架构模式也要熟稔于心。正如看到一个设计模式的名字脑里就能浮现出大致的结构图，当我们看到一个架构模式的名字时，也要马上想到对应的架构图及其基本特点。比如，当谈到分层架构时，我们就应该想起它的架构图是怎样的、有哪些出色的架构特征（architecture characteristics）、系统是如何部署的、数据存储的策略是哪种、等等。
一般地，架构模式大致可以分成两类，单体架构（monolithic architecture）和分布式架构（distributed architecture）。本系列文章将会介绍以下8种常用的架构模式：
单体架构
 分层架构（Layered architecture） 管道架构（Pipeline architecture） 微内核架构（Microkernel architecture）  分布式架构
 基于服务的架构（Service-based architecture） 事件驱动架构（Event-driven architecture） 基于空间的架构（Space-based architecture） 面向服务的架构（Service-oriented architecture） 微服务架构（Microservices architecture）  软件设计中的谬误 在介绍架构模式前，我们先谈谈软件设计中的谬误（fallacy）。所谓谬误，就是在设计软件系统，特别是分布式系统时，我们先入为主地假设它们是正确，但实际上并非如此的一些观念。这些观念都是我们在设计软件时考虑不周的体现。
谬误1：网络是可靠的 很多软件工程师常常假设网络是可靠的，但实际并非如此。相比20年前，现在的网络会可靠很多，但是仍然具有很大的不确定性。如上图所述，Serivce B可能完全是正常运行的，但是因为网络的问题，Service A发出的请求无法到达Service B。一种更糟糕的场景是，Service B可以收到Service A的请求，并处理了相关的数据，但是网络问题导致了Service A无法收到Service B的响应，从而造成了数据不一致。网络的不可靠也是为什么系统中常常出现服务通信超时、服务熔断等的原因。
总而言之，如果假设网络是可靠的，那么我们设计出来的软件系统将会是不可靠的。
谬误2：时延是0 如上图所示，服务内组件间的函数/方法级别的调用，耗时是微妙，甚至是纳秒级别；但是服务间的远程调用（比如REST、消息队列、RPC），耗时会是微秒级别，甚至在异常场景会达到了秒级！在设计系统，特别是分布式系统时，时延是一个无法被忽视的因素，我们必须清楚系统的平均时延，否则设计出来的方案可能根本不可行。比如，假设系统中服务间通信时延为100ms，如果一个请求的调用链涉及到10个服务，那么该请求的时延将会是1000ms！这么高的平均时延对于一般系统来说是完全无法接受的。
进行系统设计时，考虑平均时延还不够，更重要的是95th和99th百分点。一个系统的平均时延可能仅仅只有数十毫秒，但是95th百分点的时延却达到了数百毫秒，很多时候，这也恰恰成为了拖垮整系统性能的那块“短板”。
谬误3：带宽是无限的 在单体架构中，业务流程都在单服务内闭环，消耗的带宽很少甚至为0，因此带宽并不是主要关注点。一旦将系统拆分成分布式架构，一个业务流程可能涉及多个服务间的通信，带宽就成了必须考虑的因素。带宽的不足，会导致网络变慢，从而影响系统的时延（谬误2：时延是0）和可靠性（谬误1：网络是可靠的）。
如上图所示，假设在一个Web系统中，Service A负责处理前端请求，Service B负责管理用户信息（包括姓名、性别、年龄等45个属性）。Service A每处理一个请求都需要向Service B查询用户姓名（200 bytes），而在一次请求中，Service B却返回了用户的所有信息（500 kb）。如果系统每秒处理2000次请求，每次请求消耗500 kb带宽，那么每秒消耗的总带宽会是1 Gb！如果Service B仅仅返回必须的姓名，那么同等条件下，每秒消耗的总带宽仅仅是400 kb。
此类问题就是所谓的stamp coupling，解决方法也很多，比如在请求中添加属性选择，使用GraphQL替代REST。相比于这些技术手段，更重要的是确定服务间通信所需的最小数据集，并在进行系统设计时将其作为一个重点关注的因素。
谬误4：网络是安全的 VPN、防火墙等的广泛使用，使得很多工程师在设计系统时忽略了“网络是不安全的”这一重要原则。特别是从单体架构演进到分布式架构以后，系统被攻击的概率将会大大增加。因此，在分布式系统中，每个服务都必须是安全的endpoint，这样才能确保任何未知或恶意的请求都被拦截掉。当然，安全是有代价的，这也是像微服务架构这类细服务粒度的系统，一次业务请求中调用链过长后性能极速下降的重要原因。
谬误5：网络拓扑一成不变 这里的网络拓扑指的是系统运行时所涉及到的网络设备，包括所有的路由器、防火墙、集线器、交换机等。很多工程师会假设网络拓扑是固定的，然而并非如此。</description>
    </item>
    
  </channel>
</rss>
