3.13

查看英文版

3.13 网络与连接

概述与动机

应用程序发出的每一个请求都要跨越网络,而网络并不在乎你的期限。在你的代码与数据库、支付服务商或浏览器之间,横亘着一整套不断运作的部件:名称解析、路由、拥塞控制、加密握手、负载均衡器、代理和防火墙。大多数应用工程师把这一切都当作一条扁平、可靠的管道来看待,而这种假设恰恰是生产事故最丰富的单一来源。经典的分布式计算的谬误(网络是可靠的、延迟为零、带宽是无限的、拓扑永远不变、传输成本为零)恰好点出了那些把小故障变成大规模中断的信念。本章并非一门网络认证课程,而是应用工程师真正需要的实践知识,用于构建在网络出问题时仍能保持运行的系统。

对于大型组织而言,连接是架构同时与物理和政治相遇之处。一家全球性企业需要把数据中心、云区域、合作伙伴 API 和遗留系统缝合在一起,每一跳都会增加延迟、故障模式,以及一个必须有人负责的安全边界。各国政府又层层加码,对流量如何进出其网络以及公民数据可以流向何处制定了严格规则。理解网络的团队与忽视网络的团队之间的差异,会体现在可用性数字、页面加载时间、数据泄露报告和审计结果上。本节内容与分布式系统(第 3.3 章)、可扩展性与弹性(第 3.5 章)、基础设施与云安全(第 4.3 章)以及密码学与密钥管理(第 4.8 章)相关联。

好消息是,你不需要精通路由协议就能构建具有弹性的系统。你需要知道哪些层与你的决策相关、延迟从何而来、名称如何解析、连接如何被保护和均衡,以及如何在网络边界优雅地失败。做对这些,网络的大部分就会成为一个可依赖的基础。

关键原则

  • 网络是一种依赖,而非理所当然的存在。 把每一次远程调用都当作可能变慢、丢失,或在是否完成这件事上撒谎的东西。
  • 延迟由距离和往返次数决定。 你无法超越光速,所以要减少往返次数,把数据移到离用户更近的地方。
  • 名称出故障的频率高于机器本身。 名称解析和证书造成了惊人比例的中断,因此应把它们当作头等运维关切。
  • 有意识地保护和终止加密。 清楚地知道流量在哪里被加密、在哪里被解密,以及密钥由谁掌握。
  • 每一个网络边界都需要超时和回退机制。 无限等待和盲目重试会把一个缓慢的依赖变成一场全局性的中断。
  • 在边缘默认拒绝。 对网络进行分段,控制能离开的流量,并假设边界已经存在漏洞。
  • 观测连接本身,而不仅仅是代码。 连接错误、重传、握手时间和 DNS 延迟是日志通常会遗漏的信号。

建议

理解真正影响你决策的分层

你不需要把完整的七层模型背下来,但你确实需要一张心智地图。在传输层,传输控制协议(TCP)以握手和队头阻塞为代价,为你提供有序、可靠的字节流,而 UDP(User Datagram Protocol,用户数据报协议)则提供廉价、无序、且不保证送达的数据报。可靠的请求/响应流量走 TCP;实时媒体、游戏以及部分遥测数据走 UDP,因为对它们而言,一个迟到的数据包比一个丢失的数据包更糟糕。

超文本传输协议(HTTP)的演进改变了你的性能上限。HTTP/1.1 一次只能在一个连接上处理一个请求,因此浏览器会打开许多连接,你也要为重复的握手买单。HTTP/2 在一条 TCP 连接上多路复用许多流,消除了应用层的队头阻塞,但没有消除 TCP 层面的队头阻塞:一个丢失的数据包会使该连接上的所有流都停滞。HTTP/3 运行在 QUIC 之上,这是一种基于 UDP 的传输协议,为每个流提供独立的传送、更快的连接建立,以及跨网络变化时的连接迁移能力。你很少会亲自实现这些协议,但你会在负载均衡器、内容分发网络和客户端中选择它们,而这个选择会体现在尾部延迟上。

把 DNS 和证书当作生产系统对待

域名系统(DNS)把人类可读的名称转换为地址,几乎每一个请求都要先经过它。相当多的重大中断都可以追溯到 DNS:一次糟糕的记录变更、一个过期的区域、一个配置错误的解析器、一个提供陈旧应答的缓存层,或是一台缓慢的权威服务器为首字节响应增加了数百毫秒。对待 DNS 变更要像对待代码部署一样严谨。使用合理的生存时间(TTL)值,这样你既能在事故期间快速迁移流量,又不会在正常运行时招致陈旧缓存,并把解析延迟和失败率当作真实指标来监控。

证书同样值得认真对待。当传输层安全(TLS)证书在无人察觉的情况下过期时,整个服务会一齐陷入黑暗,而且这种故障看起来完全不像代码缺陷。要自动化证书的签发与续期,集中跟踪到期日期,并在截止日期前及早发出告警。要有意识地决定 TLS 在何处终止:在边缘负载均衡器、在代理,还是一路终止到服务本身。在边缘终止可以简化内部流量,但除非你重新加密,否则内部这一跳将不被加密。证书颁发机构、密钥轮换和密码套件选择在第 4.8 章中讨论;这里的运维要点是,DNS 和证书往往悄无声息地失效,并把一切都一并拖垮,因此要对两者都进行监测和自动化。

在正确的层进行负载均衡,并让代理发挥作用

负载均衡在众多后端之间分散流量,而你在哪一层做这件事至关重要。第四层(L4)负载均衡器按 IP 地址和端口路由,不读取有效载荷,因此速度快、与协议无关、成本低。第七层(L7)负载均衡器理解 HTTP,因此可以按路径或请求头路由、终止 TLS、重试幂等请求并强制执行速率限制,代价是每个请求要做更多工作。大多数应用流量希望在边缘有一个 L7 反向代理或 API 网关,让你有一个统一的地方来处理 TLS、身份验证、路由和可观测性。把 L4 留给原始吞吐量或非 HTTP 协议使用。

健康检查是让负载均衡变得安全的关键。要把健康检查配置为反映真实的就绪状态,而不仅仅是“进程还活着”,这样一个无法连接到其数据库的后端会在开始返回错误之前就被从轮转中摘除,并在部署时排空连接,让正在处理中的请求得以完成。API 网关把跨切面关注点(身份验证、速率限制、请求整形、版本管理)集中起来,但也会成为一个关键依赖和潜在瓶颈,因此要给它和任何核心服务一样的可用性预算和可观测性。

借助 CDN 和边缘把数据移到离用户更近的地方

延迟主要由往返时间决定,而往返时间主要由距离决定。内容分发网络(CDN)在靠近用户的接入点缓存内容,这样静态资产、以及越来越多的动态和个性化响应,就能从几毫秒之外而不是跨越一片大洋来提供服务。对于任何面向地理上分散受众的用户产品而言,CDN 是你能做出的回报最高的性能投资之一,它同时还能充当吸收流量高峰和体量型攻击的盾牌。

把工作尽可能推到边缘。在边缘终止 TLS 可以缩短握手延迟,因为昂贵的往返发生在离用户很近的地方,而在边缘位置缓存 API 响应则能缩短常见请求的路径长度。代价是缓存失效:数据缓存得越近、越多,就越难保证新鲜度,因此要明确说明哪些数据可能是陈旧的,以及可以陈旧多久。这与第 3.5 章中关于缓存与性能的讨论相关联。

让网络边界默认具有弹性

每一次远程调用都是网络可能伤害你的地方,因此要用同样的纪律来包裹每一次调用。为每一次调用设置明确的超时,因为一个挂起的依赖会耗尽你的连接池和线程池,并使其后的一切都陷入停滞。只重试那些可以安全重复执行的操作,使用带抖动的指数退避,以免一次小故障演变成同步重试风暴,并限定尝试总次数和总时间。加入断路器,这样在失败达到某个阈值之后,你会在一个冷却期内快速失败,而不是继续把请求堆积到一个已经不堪重负的服务上。这些模式在第 3.3 章有深入介绍;这里要说明的是,它们应当具体地位于网络边界,最好是作为共享平台的默认设置,而不是让每个团队各自重新发明一遍。

沿调用链为超时做好预算分配。如果一个面向用户的请求有两秒钟的预算,并且要跨越四跳,那么每一跳都必须知道还剩下多少时间,并选择快速失败,而不是继续重试直至石沉大海。通过连接池和保持连接(keep-alive)来复用连接,这样你就不必为每个请求都支付一次全新的 TCP 和 TLS 握手,并且要关注尾部延迟而不仅仅是平均值,因为用户记住的、以及在负载下产生连锁反应的,正是那最慢的百分之一。

设计并治理你的网络拓扑

在云上,你的网络就是你所配置的软件,因此要有意识地去配置它。把工作负载放入虚拟私有云(VPC)并对其进行分段:面向公众的层、应用层和数据层放在各自独立的子网中,规则只允许本应存在的流量通过。像控制入站流量一样审慎地控制出站流量。不受控制的出站访问,正是数据在遭遇入侵时得以外泄、以及被攻陷的工作负载得以联系命令与控制服务器的方式,因此要把出站流量通过受控网关路由,并对真正需要到达的目的地设置允许列表。要为 IPv6 做好规划,而不是把它当作事后补充,因为地址耗尽和合作伙伴要求终将迫使你采用它,而事后改造将十分痛苦。

采用零信任安全模型:不要再把“网络内部”当作可信任的,而是基于身份而非网络位置来验证和授权每一个请求。在实践中,这意味着服务之间采用双向 TLS、使用短期有效的凭证,以及不因请求来自相邻子网就假定其安全的策略。服务网格(service mesh)可以较为统一地实现这些能力的大部分。通过在每个服务旁运行一个边车代理,服务网格能在不改动应用代码的情况下为你提供双向 TLS、一致的重试与超时策略,以及逐跳遥测数据。它会增加运维复杂性和一定的延迟,因此应当在你的服务数量使得这种统一、无需改代码的强制实施物有所值时再采用它。零信任与网络分段将在第 4.3 章和第 8.3 章中进一步展开。

权衡:利弊

决策优点缺点/代价
L7 负载均衡器/API 网关智能路由、TLS 终止、身份验证、速率限制、可观测性每个请求的延迟更高,是一个关键的共享依赖
L4 负载均衡器快速、与协议无关、成本低无法查看或处理 HTTP,没有基于内容的路由
边缘 TLS 终止握手更快,后端更简单内部这一跳除非重新加密,否则不加密
CDN 与边缘缓存延迟收益大,可吸收流量高峰和攻击缓存失效与陈旧问题,额外的成本和配置
服务网格统一的 mTLS、重试、遥测,无需改动应用代码运维复杂性,边车延迟与资源开销
基于 QUIC 的 HTTP/3没有传输层的队头阻塞,建立速度快,可连接迁移工具链较新,UDP 有时会被限速,调试更难

核心张力存在于控制与简单性之间。你在网络边界添加的每一个功能强大的组件(L7 网关、服务网格、CDN、出站代理)都会为你带来路由智能、安全强制和可见性,但每一个也都会增加一跳、一种故障模式,以及一项需要运维的工作。解决之道是:只有当足够多的团队需要共享关切时,才把它们推入共享基础设施,以此证明运维负担是值得的,同时保持快速路径尽量简短。一支两人组成的创业团队在托管负载均衡器上终止 TLS 便宣告完成,这比同一团队手工搭建服务网格是更好的权衡。而一家拥有上千个服务、却没有统一双向 TLS 和出站控制的企业,做出的则是更糟的权衡。

与团队讨论的问题

  1. 在你各条请求路径中,TLS 分别在哪里终止,团队里每个人画出来的图是否一致? 这听起来像是无关紧要的琐事,直到事故发生。如果团队中一半人相信流量是端到端加密的,而另一半人知道流量在边缘被解密、以明文发送到后端,你面临的就既是安全缺口,也是调试陷阱。对于大型组织而言,这个问题直接映射到合规问题:监管机构和审计人员会问公民或客户数据在何处以明文形式传输,而“我们不确定”本身就是一项审计发现。带上一张从客户端到数据库某条真实路径的实际图,标出加密开始和结束的每一个点,以及每张证书和每把密钥由谁持有。答案应当告诉你是否需要内部重新加密、双向 TLS 应部署在何处,以及哪些证书一旦过期会导致某个服务下线。如果没有人能自信地画出这张图,那个缺口就是你的第一项任务。

  2. 当 DNS 变慢或出错时,你的系统会发生什么,你真的测试过吗? DNS 位于几乎每一个请求的上游,然而大多数团队从未在 DNS 退化的情况下观察过自己的系统表现。一个缓慢的解析器会为每一次新建连接增加延迟,一个陈旧的缓存可能把流量发送到一台已经下线的主机,而一次糟糕的记录变更可以在几秒钟内让整个服务陷入黑洞。在大型企业中,影响范围更广,因为内部服务发现、合作伙伴集成和云端点都依赖于名称解析。带上你的 DNS TTL 设置、你的解析延迟指标(如果有的话),以及应对糟糕记录变更的操作手册,然后问一问在事故期间你实际能多快切换流量。答案应当决定你是否要把解析延迟当作头等指标来监控、为敏捷性和缓存效率两方面调优 TTL,以及是否要演练 DNS 故障切换。如果你从未在受控测试中主动诱发过 DNS 故障,那个实验就应该被排上日程。

  3. 网络边界上的哪些弹性模式是平台默认提供的,又有哪些是每个团队都在各自重新发明的? 超时、带抖动的有限重试、断路器、连接池以及逐跳追踪,在一次性构建并被所有人继承的情况下,成本最低、也最可靠。如果交给各个团队自行处理,它们就会逐渐分化:有些调用没有超时,有些重试了非幂等操作,有些不产生任何连接级别的遥测数据,而这些缺口只会在负载之下才会显现。对于大型团队而言,这是一个组织层面的选择:弹性能力究竟应存在于共享库或平台层,还是分散在各个服务之中。带上一份对若干服务的抽样审计,统计有多少服务在每次远程调用上都设置了明确的超时,并端到端地传递关联标识符。如果这个比例很低,解决办法就是平台投入,而将其标准化也能让弹性变得可测试、可审计,这在受监管行业中越来越重要。答案应当告诉你,是应该为网络平台能力投入资金,还是继续为事故中的不一致买单。

  4. 你的每一个工作负载现在能够到达公共互联网上的哪些地方,又是谁批准了每一个出站目的地? 入站流量总是更受关注,因为攻击者是从那里敲门的,但出站流量才是数据在遭遇入侵时真正离开的方式,也是被攻陷的工作负载与命令控制服务器“打电话回家”的渠道。大多数团队能更容易地列出谁在和自己说话,却很难说清自己在和谁说话,而这种不对称正是攻击者会利用的缺口。与之相竞争的考量是摩擦:一份经批准的目的地允许列表,会拖慢那些想要立刻调用某个新第三方 API 的开发者,因此真正诚实的争论在于,你愿意用多少便利去换取一个更小的攻击面。带上某个代表性服务当前的出站规则、过去一周内它实际连接过哪些地方的抓包记录,以及(如果有的话)批准新目的地的流程。对企业和政府系统而言,这不是可有可无的卫生习惯,而是一项审计条目:边界保护和出站清单正是监管机构和网络边界规则要求你出具的东西,而“任何工作负载都能到达任何地方”是一项会被要求整改的审计发现。

  5. 你的超时和重试沿每条调用链是否组合成一个连贯的预算,还是每一跳都在各自孤立地猜测? 一个跨越四个服务的面向用户请求,只有一个用户真正能感受到的截止时间,然而每一跳通常都会在本地各自设置超时,重试一个早已放弃处理的服务,一边做着额外的无用功,一边突破了端到端的预算。对于大型团队而言,危险之处在于这是涌现出来的:每个服务各自看来合理的超时设置,叠加在一起就会形成级联停滞和同步的重试风暴,而这一点是任何单一团队都无法从自己的仪表盘上看出来的。这里的张力存在于本地自主性(每个团队调优自己的限制)与一个被传播的截止时间(每一跳都读取并随时间消耗而缩短它)之间。带上一条真实的请求路径、每一跳的超时和重试策略、产品所承诺的端到端预算,以及你在负载下的尾部延迟数字(p99,而不是平均值)。在受监管和高可用性场景中,要把这一点与你的恢复目标联系起来:一条无法在预算内快速失败的调用链,会把一个缓慢的依赖变成一次被突破的服务水平目标,而那次突破正是管理层和审计人员会要求你解释的数字。

  6. 在多大的服务数量和流量规模下,统一强制实施(服务网格、L7 网关、边缘缓存)才能物有所值,而你今天正处在这条曲线的哪个位置? 你在网络边界添加的每一个功能强大的组件,都会带来路由智能、安全性和可见性,但每一个也都会增加一跳、一种故障模式,以及一项需要全天候运维的工作。太早采用服务网格,会让为数不多的几个服务淹没在边车复杂性之中;太晚采用,则会让你拥有上千个服务却没有统一的双向 TLS 或一致的重试策略。相互竞争的考量是:跨众多团队实现无需改代码、一致的强制实施所带来的价值,与运行控制平面的真实成本、增加的延迟,以及能够调试它的稀缺人才之间的权衡。带上你当前的服务数量和增长曲线、已经使用能提供同等保证的共享客户端的服务比例,以及你在延迟上还有多少余量可以支出。对于大型企业或政府机构而言,这也是一个治理层面的决策:服务网格或中央网关能让一个平台团队一次性在全组织推行某项策略,这对合规而言是强大的能力,但如果那个单点被资源不足所拖累,就会十分危险,因此要把它作为核心基础设施来预算,拥有自己的可用性目标,而不是当作一个附带项目。

行业视角

创业公司。 依靠托管基础设施,把稀缺的工程注意力花在产品上,而不是数据包上。一个使用自动续期证书来终止 TLS 的托管 L7 负载均衡器,再加上应用前面的一个 CDN,就能在不需要运维团队的情况下,为你带来加密、负载均衡、全球快速的流量。用一个带有超时和有限重试的小型共享客户端包裹每一次外部调用,并在服务数量远多于运维人力之前,抵制住引入服务网格的冲动。

小型企业。 你没有网络专家,预算也紧张,因此应把连接性当作一种已配置好可以直接购买的东西,而不是自己搭建的东西。选择一个默认设置已经提供自动化证书、DNS 管理和合理防火墙的云服务商或平台,直接启用它们提供的功能,而不是自己动手拼装。在必须做出选择的地方,优先选择托管选项:付费让供应商续期证书、监控 DNS,远比一次因证书遗忘过期而造成的中断要便宜得多。

企业。 你面临的问题是如何在众多团队和地区之间保持一致性:统一的双向 TLS、标准化的超时与重试、受控的出站流量,以及没有任何一个团队可以自行退出的证书和 DNS 监控。把这些推入共享平台基础设施(服务网格、内部网关、共享客户端库),让弹性成为被继承而来的能力,而不是被重新发明的东西,并以和任何核心服务同样的可用性预算和可观测性来管理网络边界。对 VPC 进行分段,集中治理出站流量,把拓扑当作需要审计的软件来对待。

政府。 采购规则、透明度和公共问责制塑造着每一个边界。把面向互联网的流量汇聚到一小组经过加固并受到监控的网关,清点每一个外部端点,并运行一套零信任架构,让服务通过身份而非网络位置、以短期有效的凭证进行相互验证。把 DNS 和证书管理当作关键基础设施,配备专门的监控,因为面向公民的服务上一张过期的证书,就会同时招致公众和立法机构的审视,并让证据保持可审计状态,使边界保护评审能够找到一份有据可查、站得住脚的设计。

示例

创业公司。 一家十人规模的软件即服务公司,把所有业务都运行在一个单一的托管 L7 负载均衡器之后,该负载均衡器使用自动续期的证书来终止 TLS,并在其 Web 应用和 API 前面部署了一个 CDN。这一组合为他们带来了快速的全球页面加载速度,吸收了产品发布带来的偶发流量高峰,并在没有专职运维团队的情况下保护了源站。他们为每一次调用支付服务商和邮件服务的请求都设置了明确的超时和有限重试,并封装在一个小型共享客户端中,这样一个缓慢的第三方就永远不会挂起用户请求。他们抵制引入服务网格:在只有十几个服务的情况下,运维成本将远远超过收益,而托管基础设施已经为他们提供了加密、负载均衡的流量。

企业。 一家跨国零售商在三个云区域和一个遗留的本地数据中心中运行业务,彼此通过专线而非公共互联网连接,因此库存和支付流量从不经过开放网络。每个区域都位于一个经过分段的 VPC 中,拥有独立的公共、应用和数据子网,所有出站流量都通过出站网关,网关对已批准的目的地设置了允许列表,因此一个被攻陷的工作负载无法悄悄外泄数据。数百个服务通过一个服务网格进行通信,该网格在各处强制实施双向 TLS,并应用统一的重试、超时和追踪策略,使中央平台团队无需接触应用代码就能推出新的重试策略。集中式证书监控会提前数天标记出即将到期的证书,自动化系统会在任何客户察觉之前完成轮换。

政府。 一个国家级机构在网络边界保护规则下运营,这些规则要求所有面向互联网的流量都汇聚到一小组经过加固并受到监控的网关,与可信互联网连接(trusted internet connections)模型保持一致。机构间的流量通过专线传输,每一个外部端点都被清点在册,因此安全团队确切知道什么可以进出。该机构运行一套零信任架构,服务之间通过身份、使用短期有效的凭证相互验证,没有任何请求仅仅因为源自边界内部就被信任。DNS 和证书管理被当作关键基础设施,配备专门的监控,因为一张过期的证书或一次糟糕的区域变更,都可能使一个面向公民的福利门户离线,并引发公众和立法机构的双重审视。

商业理由:动机、投资回报率与总拥有成本

网络方面的纪律成本低廉,而缺乏这种纪律的代价则会在最糟糕的时刻付出。这项投资大多是一次性的、具有平台形态:带超时和重试的共享客户端、自动化的证书管理、DNS 监控、经过合理分段的 VPC,以及边缘缓存。每一项都会让继承它的每个团队受益,因此每个团队的边际成本很低,而回报却在不断累积。CDN 尤其常常能带来双重回报,既降低源站带宽成本,又通过更快的页面加载改善随之而来的转化率和参与度数字。

跳过这项工作的代价,要用中断和数据泄露来衡量。一张过期的证书或一次糟糕的 DNS 变更,可能在几分钟内让整个产品下线,而修复工作却因为工程师排查错了层而被延误。缺失的超时会把一个缓慢的依赖级联成整个平台的停滞。不受控制的出站流量会把一个被攻陷的工作负载变成一场数据外泄事件。要用领导层已经在跟踪的指标来阐述这个理由:可用性、平均恢复时间、页面加载时间和数据泄露风险。自动化的证书和 DNS 管理能防止一整类自我造成的中断,边缘和 CDN 投资能撬动一个产品性能指标,而分段和出站控制则能缩小数据泄露的影响范围。总拥有成本这一论点,正是贯穿本指南始终反复出现的那个论点:把能力内建进来,只是在事故最终迫使问题浮出水面之后再去补建它的一小部分成本。

反模式与陷阱

  • 假设网络是可靠且快速的。 编写代码时把远程调用当作本地调用来处理,没有超时、没有重试,也没有对“超时了但也许已经完成”这种情况的处理。
  • 手工管理证书。 用电子表格或某个人的记忆来追踪到期时间,一旦被遗忘,就注定会在某一刻发生中断。
  • 把 DNS 当作与运维无关的系统来忽视。 没有解析监控、TTL 设置随意,记录变更也没有部署应有的严谨性。
  • 在没有幂等性或退避机制的情况下重试。 重复的副作用和同步的重试风暴,会把一次小故障放大成一场中断。
  • 信任内部网络。 把边界内的任何东西都当作安全的,内部流量不加密,也没有基于身份的授权。
  • 不受控制的出站流量。 允许工作负载到达任意出站目的地,把一条数据外泄路径和一条通往命令服务器的通道拱手让给攻击者。
  • 过于“健谈”的请求路径。 深层的同步调用链,每一跳都增加一次往返,导致尾部延迟在负载下急剧膨胀。
  • 过早采用服务网格。 为数量不多、用一个共享客户端就能更好地服务的几个服务,承担边车带来的复杂性和延迟。

成熟度模型

  • 第 1 级,启动: 远程调用被当作本地调用来处理。超时和重试缺失或过于简单,“超时了但也许已经完成”这种情况未被处理。证书和 DNS 靠手工管理,会造成意外中断。没有分段,内部流量默认被信任。网络连接方面的工作是被动的,只有在事故迫使之后才会发生。
  • 第 2 级,发展: 一些团队已经采用了基本实践,但在各个服务之间并不一致。某些地方存在超时和简单重试,TLS 在负载均衡器处终止,证书大多已实现自动化。CDN 承载静态内容,基本的网络分段已经存在,但出站流量大体上是开放的,每个团队都各自发明自己的客户端。一个团队做得好的事情,另一个团队可能还没有开始。
  • 第 3 级,标准化: 具有弹性的网络连接方式已被记录在案并在全组织范围内强制执行。超时、带抖动的退避和断路器通过共享库或每个团队都会继承的网关成为标准做法。DNS 和证书被当作生产系统一样进行监控和自动化,VPC 已分段并具有受控的入站和出站规则,连接级别的遥测数据在各处都被采集,零信任原则正作为一项政策而非某个团队的实验被采纳。
  • 第 4 级,管理: 网络边界不仅被标准化,还被对照基线进行度量和控制。解析延迟、TLS 握手时间、重传和连接错误率、尾部延迟(p99,而非平均值)、证书到期提前量以及出站策略违规,都在带有告警阈值和错误预算的仪表盘上被追踪。放行/不放行的决策和容量决策都由这些数据驱动,主动诱发的 DNS 和依赖故障演练按计划进行并度量其结果,任何信号的退化都会被及时发现并落实到具体负责人,而不是等到下一次中断时才被发现。
  • 第 5 级,编排: 具有弹性的网络连接是持续改进的平台默认设置,在整个组织中被整合,并能随变化而自适应。双向 TLS 和基于身份的授权是统一的,通常通过服务网格实现;边缘和 CDN 策略根据实时延迟数据进行调优;出站流量得到全面治理;拓扑、供应商和路由选择会随着成本、风险和流量的变化而重新平衡。网络方面的决策被编织进容量规划、安全规划和业务规划之中,组织会把往返次数、尾部延迟和边界故障模式作为日常事务来明确考量。

讨论话题

  1. 如果你的主 DNS 提供商或解析器出现一小时的性能下降,你的系统还有多少部分能继续正常工作,你又如何知道?
  2. 你的哪些服务在流量进入网络“内部”之后仍以明文方式发送,要弥合这个缺口需要付出什么?
  3. 你架构中最深的同步调用链在哪里,一个典型用户请求实际会产生多少次网络往返?
  4. 你的超时设置沿调用链能否组合成一个连贯的预算,还是每一层都各自设置、自求多福?
  5. 你的工作负载现在能够到达公共互联网上的哪些地方,又是谁批准了每一个出站目的地?
  6. 在你的组织中,服务数量达到多少时,服务网格带来的统一强制实施收益才能超过其运维成本,而你现在距离这个数字还有多远?

关键要点

  • 网络是一种拥有自身故障模式的依赖;要为缓慢、丢失和模糊不清的完成状态设计每一次远程调用,而不仅仅是为成功或干净利落的失败设计。
  • 延迟由往返次数和距离决定,因此要减少跳数、复用连接,并借助 CDN 和边缘把数据移到离用户更近的地方。
  • DNS 和 TLS 证书会悄无声息地失效,并使整个服务陷入瘫痪;要像对待生产系统一样自动化并监控两者。
  • 在与流量相符的层面上进行负载均衡,只有在可用性和可观测性成本合理时,才把共享关切放到一个 L7 网关之后。
  • 通过超时、带抖动的有限重试和断路器,让网络边界默认具有弹性,理想情况下作为被继承的平台默认设置。
  • 对你的 VPC 进行分段、治理出站流量、为 IPv6 做好规划,并采用零信任,使“身处网络内部”本身不再自动赋予信任。

参考文献与延伸阅读

  • W. Richard Stevens, TCP/IP Illustrated, Volume 1: The Protocols
  • Ilya Grigorik, High Performance Browser Networking
  • Cricket Liu and Paul Albitz, DNS and BIND
  • Andrew S. Tanenbaum and David J. Wetherall, Computer Networks
  • Michael Nygard, Release It!: Design and Deploy Production-Ready Software
  • Evan Gilman and Doug Barth, Zero Trust Networks: Building Secure Systems in Untrusted Networks
  • Lee Calcote and Zack Butcher, Istio: Up and Running (service mesh concepts)
  • Internet Engineering Task Force, RFC 9110 (HTTP Semantics) and RFC 9000 (QUIC)
  • Peter Deutsch and James Gosling, “The Eight Fallacies of Distributed Computing”
  • National Institute of Standards and Technology, Special Publication 800-207: Zero Trust Architecture