分布式架构的谬误

493 阅读8分钟

分布式架构的谬误

分布式架构风格虽然在性能、可扩展性和可用性方面比单体架构风格强大得多,但这种强大的性能也有很大的折衷。所有分布式架构所面临的第一组问题被描述为分布式计算的谬误,这谬误最早是由Sun Microsystems公司的L.Peter Deutsch和他的同事在1994年提出的。谬误是指人们相信或假设为真但并非如此的东西,分布式计算的所有八个谬误都适用于今天的分布式架构。下面的描述了每个谬误。

谬误1:网络是可靠的

开发人员和架构师都认为网络是可靠的,但事实并非如此。虽然随着时间的推移,网络确实越来越可靠,但事实是,网络仍然普遍不可靠。这对所有的分布式架构都很重要,因为所有的分布式架构风格都依赖于网络来往于服务以及服务之间的通信。如下图所示,服务B可能是完全健康的,但由于网络问题,服务A无法到达它;或者更糟糕的是,服务A向服务B提出了处理一些数据的请求,但由于网络问题,没有收到响应。这就是为什么在服务之间存在超时和断路这样的事情。一个系统越是依赖网络(比如微服务架构),它的潜在可靠性就越低。

谬误2:零延迟

如上图所示,当通过方法或函数对另一个组件进行本地调用时,该时间(t_local)以纳秒或微秒为单位。然而,当通过远程访问协议(如REST、消息传递或RPC)进行同样的调用时,访问该服务所测量的时间(t_remote)以毫秒为单位。因此,t_remote将始终大于t_local。任何分布式架构中的延迟都不是零,然而大多数架构师都忽略了这一谬误,坚持认为他们拥有快速的网络。问问你自己这个问题:你知道在你的生产环境中,一个RESTful调用的平均往返延迟是多少吗?是60毫秒?还是500毫秒?

在使用任何分布式架构时,架构师必须知道这个延迟平均值。它是确定分布式架构是否可行的唯一方法,特别是在考虑采用微服务架构风格时,因为服务的细粒度和这些服务之间的通信量。假设每个请求的平均延迟为100毫秒,把10个服务调用链在一起执行一个特定的业务功能,就会变成一个延迟1000毫秒的请求! 了解平均延迟是很重要的,但更重要的是还要最差延迟。虽然平均延迟可能只有60毫秒,但最差延迟可能是400毫秒! 通常正是这种最差延迟会扼杀分布式架构的性能。在大多数情况下,架构师可以从网络运维那里了解到延迟值。

谬误3:带宽是无限的

在单体架构中,带宽通常不是一个问题,因为处理业务请求基本不需要带宽。但是,如上图所示,一旦系统在微服务等分布式架构中被拆分成更小的服务,这些服务之间的通信就会大量利用带宽,导致网络速度变慢,从而影响网络的延迟和可靠性。

为了说明这个谬误的重要性,请看上图所示的两个服务。假设左边的服务管理购物车,右边的服务管理客户信息。每当请求进入购物车服务,由于购物车服务中没有保存客户信息,它需要向右边的客户服务进行服务间调用,以获得客户名称。客户资料服务返回几十个属性共500 kb给愿望清单服务,而购物车服务只需要名字(200字节)。这是一种被称为邮票耦合的耦合形式。这看起来可能没什么,但假如每秒对购物车发出2000次请求呢?这意味着从购物车服务到客户服务的这种服务间调用每秒发出2000次。按每个请求500 kb计算,这一次服务间调用(在那一秒进行的数百次调用中)所使用的带宽为1 Gb!

分布式架构中的邮票耦合会消耗大量的带宽。如果客户资料服务只传回愿望清单服务所需要的数据(本例中为200字节),那么传输数据所使用的总带宽只有400kb。邮票耦合可以通过以下方式解决:

  • 创建专用的RESTful API

  • 在契约中使用字段选择器

  • 使用GraphQL来解耦契约

  • 使用值驱动的契约和消费者驱动的契约(CDCs)

  • 使用内部消息传递接口

无论使用何种技术,确保在分布式架构中的服务或系统之间传递最少的数据量是解决这一谬误的最佳方式。

谬误4:网络是安全的

在分布式架构中,安全变得更具挑战性。如上图所示,每个分布式部署单元的每一个接口都必须是安全的,这样未知的或不好的请求就不会进入该服务。当从单体架构转向分布式架构时,威胁和攻击的表面积会成倍增加。即使在进行服务间通信时,也必须保证每个接口的安全,这也是同步、高度分布式架构(如微服务或基于服务的架构)中性能往往较差的另一个原因。

谬误5:拓扑结构不变

这个谬误指的是整体网络拓扑结构,包括整体网络中使用的所有路由器、集线器、交换机、防火墙、网络和设备。架构师认为拓扑结构是固定的,永远不会改变。但是,它是会变化的,而且一直在变化。这个谬误是什么意思呢?

假设一个架构师在周一早上上班,发现大家都像疯了一样到处跑,因为生产环境上的服务一直在超时。可是周末明明没有部署新的服务。到底是什么原因呢?几个小时后,大家发现,当天凌晨2点有一次小型网络升级,而这个升级使所有先前的延迟假设失效,触发了超时和熔断。

架构师必须与运维和网络管理员保持不断的沟通,以了解什么是变化的,又是什么时候变化的,这样他们就可以做出相应的调整,以减少之前描述的那种意外情况。这看起来似乎很明显,很容易,但事实并非如此。事实上,这个谬误直接导致了下一个谬误。

谬误6:只有一个管理员

架构师总是陷入这种谬误,认为他们只需要与一个管理员协作和沟通。然而在一个大公司中,往往有几十个网络管理员。关于网络的延迟或拓扑结构变化,架构师应该和谁商量?这个谬误指出了分布式架构的复杂性,以及为了让所有东西都能正确工作而必须发生的协调量。单体应用由于单一部署的特性,不需要这种级别的沟通和协作。

谬误7:传输代价为零

许多架构师将这个谬误与延迟相混淆,这里的传输成本并不是指延迟,而是指与进行 "简单的RESTful调用 "相关的实际成本,即金钱。架构师不正确地做出,“必要的基础设施已经到位,并且足以进行简单的RESTful调用或拆分一个单片应用程序”这样的假设。通常不是这样的。分布式架构的成本明显高于单体架构,主要是由于增加了对额外硬件、服务器、网关、防火墙、新子网、代理等的需求。

每当着手进行分布式架构时,架构师应当分析当前服务器和网络拓扑结构的容量、带宽、延迟和安全区,不要陷入这种谬误的陷阱。

谬误8:网络是同质的

大多数架构师和开发人员都认为网络是由一个网络硬件供应商组成的,但事实却大相径庭。大多数公司的基础设施中都有多个网络硬件供应商,甚至更多。

这个谬论的意义在于,并不是所有这些异构的硬件厂商都能很好地一起发挥作用。大部分都能用,但Juniper硬件是否能与思科硬件无缝集成?网络标准经过多年的发展,使得这个问题已经不那么严重了,但事实上,并不是所有的情况、负载和环境都经过了充分的测试,因此,网络数据包偶尔会丢失。这反过来又影响了网络可靠性、延迟,以及带宽。换句话说,这个谬误与所有其他谬误联系在一起,在处理网络时形成了一个混乱和痛苦的循环(在使用分布式架构时,这是无法避免的)。

——————摘自《Software Architecture》