机器中的幽灵:分布式计算的八大谬误之旅

43 阅读7分钟

闭上眼睛,回想一下你架构的第一个系统。我的意思是,真正架构的系统——你在白板上一丝不苟地画着方框和线条,每个组件都清晰地分开,用优雅简洁的箭头进行沟通。那是一张美丽的蓝图,一座数字版的帕特农神庙。但它……是一个谎言。

这或许是一个必要的谎言。一种让我们得以开始的简化。但当我们将这种完美、单体式的思维模式应用于分布式系统混乱、杂乱的现实时,我们便踏入了一个痛苦的世界。我们并非建在坚实的土地上,而是建在一片沼泽之上,而这片沼泽被一套看似简单的真理所支配,这套真理被称为“分布式计算的八大谬误”。

这些并非只是清单上的条目;它们是一种入门仪式,一段从纯真到经验的旅程。让我们携手同行,不是以学者的身份,而是以工匠的身份,感受过我们自身准则中这些谬误的刺痛。

序章:建筑师的梦想 一切开始得非常顺利。我们将单体应用拆分成多个独立的服务。它们通过网络进行通信。如下所示:

[Service A] ---> [Network] ---> [Service B] 在我们的脑海里,那张网络是一条完美透明的线路,仅仅是我们逻辑的通道。这是所有其他谎言的根基。

混乱中的杰作的八个面板 把每一个谬误想象成三联画中的一块面板,警告我们不要傲慢。

第一小组:可靠网络的谬误

“网络很可靠。”

梦想:服务之间的连接线如同钢梁,信息如同水流经管道,始终如一。 现实:网络如同飓风中磨损的索桥,由路由器、交换机和线缆构成,构成一个复杂而复杂的“野兽”,任何一种都可能悄无声息地或声势浩大地发生故障。它会变得拥堵,配置错误,最终导致您的服务彼此隔离。 工匠的回应:我们为失败而设计。我们拥抱超时、指数退避重试和断路器。我们假设每个网络调用都可能失败,并且我们将服务编码为具有弹性,而不仅仅是充满希望。

小组讨论 2:零延迟的谬误

“延迟为零。”

梦想:跨网络调用的速度与本地函数调用一样快。我们美观、简洁的面向对象设计将完美运行! 现实:单个函数调用现在就像一场光速的千里之行,途经数十个站点。本地调用可能只需 0.1 毫秒;跨数据中心调用则可能需要 20-100 毫秒。如果再乘以数百次调用,你那流畅的 UI 就变成了一个加载条。 工匠的回应:我们专注于异步和批处理。我们通过缓存(CDN、Redis)拉近数据与数据之间的距离。我们采用最小化往返次数的 API 模式,例如GraphQL或BFF(Backend For Frontend)。我们崇尚光速。

第三小组:无限带宽的谬误

“带宽是无限的。”

梦想:我们可以毫不犹豫地发送海量负载——包含所有嵌套关系的整个对象图。网络可以处理。 现实:带宽是有限的资源,共享且存在竞争。在 1KB 即可满足需求的地方,发送 1MB 负载会阻塞网络,增加延迟,并造成实际成本。 工匠的回应:我们成为极简主义者。我们设计精简、专注的 API。我们使用协议缓冲区或 Avro而不是冗长的 JSON。我们只请求所需的数据。我们将带宽视为宝贵的商品。

小组讨论 4:安全网络的谬误

“网络是安全的。”

梦想:我们的服务位于我们“安全”的边界内,通过可信 VLAN 相互通信。这是私密的对话。 现实:内部网络是新的攻击面。一个被攻陷的节点、一个配置错误的防火墙、一个恶意的内部人员——威胁如今已深入城墙之内。 工匠的回应:我们采用零信任架构。我们对每个服务间调用(mTLS、JWT)进行身份验证和授权。我们对传输中的流量进行加密,即使是内部流量。我们假设网络是敌对的。

第五小组:稳定拓扑的谬误

“拓扑结构不会改变。”

梦想:我们的服务拥有固定的 IP 地址和主机名。我们永远知道每个人的所在地。 现实:在云和容器时代,拓扑结构瞬息万变。实例每秒都在诞生、消亡和迁移。IP 地址是短暂的。系统处于不断变化之中。 工匠的回应:我们依赖服务发现机制。我们不再硬编码端点。我们使用Consul、Etcd 或 Kubernetes 服务等工具,让系统能够动态地找到自己。

专题讨论6:单一行政管理者的谬误

“有一名管理员。”

梦想:一位仁慈无所不知的运维人员了解整个系统,能够调试并修复任何问题。 现实:您拥有一个 DevOps 团队、一个数据库团队、一个平台团队和三个不同的服务团队,每个团队都有不同的优先级、计划和访问级别。这个“系统”就像一个个“封地”的联合体。 工匠的回应:我们构建的目标是可观察性,而不仅仅是监控。我们确保我们的服务发出结构化的日志、指标和追踪信息,这些日志、指标和追踪信息跨管理边界保持一致且相互关联。我们为团队之间设计了清晰的API 和 SLA。

专题讨论七:零运输成本的谬误

“运输成本为零。”

梦想:序列化、发送和反序列化数据的操作都是免费的。这只是一个细节。 现实:数据编组和解组在计算上非常昂贵。传输协议本身(例如 HTTP/1.1 及其标头)的开销非常大。这些开销累积起来,会消耗 CPU 并增加延迟。 工匠的回应:我们明智地选择协议。在性能关键路径中,我们会考虑更高效的方案,例如gRPC而不是 REST/HTTP1。我们会分析整个请求生命周期,包括序列化。

第八小组:同质网络的谬误

“网络是同质的。”

梦想:网络是一个统一的结构,每个链路都相同。 现实:您的请求可能在一次旅程中穿越 WiFi、5G 蜂窝网络、企业局域网和跨洋光纤线路。每个网络在延迟、可靠性和 MTU(最大传输单元)方面都有不同的特性。 工匠的回应:我们以最小公分母为设计目标。我们编写了能够处理数据包丢失和重新排序的健壮客户端。我们不对 MTU 大小做任何假设。我们的系统具有自适应性。

结语:工匠的接受 穿越这些谬误的旅程,就是从程序员到分布式系统工匠的旅程。这些谬误并非需要“解决”的问题,而是需要承认和尊重的自然力量,就像引力或熵一样。

我们那份美丽而简洁的蓝图从未出错。这只是初稿。最终的杰作——真正在生产中发挥作用的系统——是我们在这份简洁之上,赋予其丰富而复杂的韧性、可观察性和谦逊的质感。

我们不再建造数字帕特农神庙,而是开始构建富有韧性的生态系统。我们拥抱混乱,并在其中学习构建能够生存的系统。作者www.lglngy.com