Day03-05|2.3.5 网络协议:分层通信、可靠传输与服务边界

对应教材:上篇·综合知识·第 2 章“计算机系统基础知识”·2.3.5 网络协议

学习定位:网络协议是计算机软件系统跨进程、跨主机和跨网络交换信息的规则集合。系统架构设计师需要理解协议分层、封装、寻址、可靠性和安全机制,才能分析接口延迟、连接耗尽、重试风暴、消息重复、网络分区和服务不可用等问题。本节重点不是背诵报文每个字段,而是掌握协议如何提供能力,以及能力背后的代价。

一、今日目标

完成本节后,应能解释网络协议为什么采用分层模型;理解应用层、传输层、网络层和链路层的职责;说明 TCP、UDP、HTTP、HTTPS、DNS 的基本特点;区分连接、会话、请求、响应和报文;掌握超时、重传、流量控制、拥塞控制、负载均衡和服务发现的基本关系;能在案例中定位网络延迟和重试引起的级联故障。

二、协议是什么

协议是通信双方共同遵守的规则,至少包括语法、语义和时序。语法规定数据如何编码和组织;语义规定字段和操作代表什么;时序规定请求、响应、确认、超时和重传何时发生。没有共同协议,发送方即使把数据送到接收方,接收方也无法正确解释。

协议要素 解决的问题 示例
编码格式 数据如何表示 JSON、二进制、字符集、字节序
地址与路由 数据发给谁、经过哪里 IP、端口、域名、路由
交互时序 先做什么、后做什么 握手、确认、响应、关闭
可靠性 丢失、乱序、重复怎么办 校验、重传、序号、幂等
流量控制 接收方能处理多少 窗口、背压、队列
安全 如何认证、保密和防篡改 TLS、签名、访问控制

协议设计的核心是让独立参与者能够互操作。协议越复杂,提供的能力越多,但实现、测试、兼容和故障排查成本也越高。架构师要根据业务重要性选择可靠性、安全和性能,而不是把所有功能都堆进一个协议。

三、分层模型与封装

网络通信通常采用分层思想。应用层表达业务语义;传输层负责端到端的数据传递;网络层负责跨网络寻址和转发;链路层负责相邻节点之间的传输;物理层负责比特或信号的实际发送。OSI 七层模型常用于概念分析,TCP/IP 模型则更常用于工程实践。

发送数据时,高层数据逐层加上本层首部,形成封装;接收方逐层去掉首部并交给上层,形成解封装。应用数据在传输层可能成为 TCP 段或 UDP 数据报,在网络层成为 IP 分组,在链路层成为帧。每一层只依赖相邻层提供的服务,便于替换实现和隔离变化。

层次 主要职责 常见问题
应用层 业务请求、响应和数据语义 版本、幂等、认证、错误码
传输层 端到端传输和端口复用 连接、丢包、窗口、拥塞
网络层 地址、路由和跨网转发 路由、TTL、分片、不可达
链路层 相邻节点传输和介质访问 帧、MAC、校验、交换
物理层 信号和比特传输 带宽、干扰、链路状态

分层并不意味着每层完全独立。MTU、分片、TLS、代理、负载均衡、内核缓冲和应用消息大小会相互影响。架构题要沿着端到端路径分析,不能只说“网络层可靠”或“TCP 已经解决一切问题”。

四、寻址、端口与连接

IP 地址标识网络中的主机或接口,端口标识主机上的进程或服务。一个 TCP 连接通常由源 IP、源端口、目的 IP 和目的端口共同确定。域名是便于人和应用使用的名称,需要通过 DNS 解析成地址。

连接建立需要握手,连接关闭也有相应的状态过程。大量短连接会产生握手、系统调用、加密协商和端口资源开销;连接长期不释放则会耗尽文件描述符、连接池和内核缓冲。连接池、Keep-Alive、HTTP/2 多路复用和合理的空闲超时,能够减少建立连接的固定成本,但也要防止空闲连接占用过多资源。

NAT、代理和负载均衡会改变实际网络路径和可见地址。架构设计中要明确客户端真实 IP 的传递、连接终止位置、TLS 终止位置、健康检查和会话保持。错误的超时配置可能出现前端已断开、代理仍等待、后端继续执行的“幽灵请求”,进而放大资源消耗。

五、TCP 与 UDP

TCP 提供面向连接的、可靠的、按序的字节流服务。它使用序号、确认、重传、滑动窗口、流量控制和拥塞控制来应对丢包、乱序和网络拥塞。TCP 不保留应用消息边界,因此应用需要设计消息长度、分隔符或帧格式,不能假设一次发送对应一次接收。

UDP 无连接,提供尽力而为的数据报服务,不保证到达、顺序和不重复。它开销较小、延迟低、适合实时音视频、广播、发现和某些自定义可靠协议,但可靠性、顺序、去重和拥塞处理需要由应用或上层协议负责。

对比项 TCP UDP
连接 有连接和状态 无连接或弱状态
可靠性 提供确认、重传和按序 默认不保证
数据边界 字节流,不保留消息边界 保留数据报边界
控制机制 流量控制、拥塞控制 通常由上层负责
适用场景 Web、数据库、文件、交易 实时流、发现、广播、低延迟

选择 TCP 或 UDP 应根据数据丢失代价、延迟容忍度、消息大小、网络环境和实现能力判断。用 UDP 不会自动获得高性能,用 TCP 也不意味着应用层不需要幂等和超时。

六、HTTP、HTTPS 与应用接口

HTTP 是请求-响应式应用层协议。请求通常包含方法、目标资源、首部和消息体;响应包含状态码、首部和消息体。GET、POST、PUT、DELETE 等方法表达不同语义,状态码帮助调用者区分成功、客户端错误和服务端错误。

HTTP 接口设计应明确资源模型、参数校验、分页、排序、错误码、幂等和版本。GET 通常应是安全且可缓存的,PUT 和 DELETE 需要谨慎处理重复请求,POST 创建操作要通过幂等键防止超时重试导致重复业务。HTTP 状态码不能代替业务错误码,调用者还需要知道余额不足、库存不足或权限不足等具体原因。

HTTPS 是 HTTP 运行在 TLS 之上,提供服务器认证、机密性和完整性。TLS 握手会消耗计算和网络往返,但连接复用、会话恢复和硬件加速可以降低开销。证书链、域名校验、密钥轮换、协议版本和终止位置都属于安全架构的一部分。

七、DNS 与服务发现

DNS 把域名解析为 IP 地址,也可以通过不同记录类型表达别名、邮件、服务和权重等信息。DNS 缓存可以降低解析延迟和权威服务压力,但缓存会导致地址变更不能立即生效,TTL 需要结合故障切换和运维需求设置。

微服务中的服务发现可以由客户端查询注册中心,也可以由代理或平台侧完成。客户端发现灵活、链路短,但每个客户端要实现健康判断、负载策略和缓存;服务端发现由负载均衡器统一处理,客户端简单,但增加中间层依赖。无论哪种模式,都要处理实例过期、网络分区、注册中心不可用和地址缓存陈旧。

八、可靠性、超时与重试

网络无法保证每个请求都及时完成。丢包、拥塞、服务繁忙、连接关闭和响应丢失都可能造成超时。超时设置太短会把正常慢请求误判为失败,太长则会占用线程、连接和队列资源。应根据端到端延迟预算分配各层超时,并留出序列化、排队和重试空间。

重试可以提高瞬时故障下的成功率,但会放大请求量。若请求已经在服务端成功执行而响应丢失,重试可能产生重复写入。因此写操作必须有幂等键、去重记录或状态查询;重试要有上限、指数退避和随机抖动;对不可重试错误立即失败;当下游持续异常时,通过熔断、限流和降级保护系统。

九、案例分析:重试风暴导致全链路雪崩

某订单接口平时延迟 300ms,数据库短暂抖动后,客户端、网关和服务内部都设置了 3 次重试。故障期间请求量迅速放大,线程池、连接池和消息队列全部耗尽。请分析原因并提出方案。

参考答案:多层重试发生乘法放大,原始请求一次失败可能产生几十次下游请求;超时设置相互独立,导致上游已经超时而下游仍继续执行;写操作可能产生重复扣款或重复订单;缺少全链路请求编号和限流,无法区分原始请求与重试请求。

应统一重试责任,通常由最接近故障语义的一层决定;设置端到端截止时间和每层预算,避免无限等待;只对明确可恢复、幂等的错误重试,并采用退避、抖动和最大次数;对数据库和核心服务启用连接池上限、舱壁隔离、熔断和队列背压;为订单操作设置幂等键和状态查询。通过请求量、重试率、超时率、连接池等待、队列长度和下游成功率验证效果。

十、综合知识练习

练习 1

下列关于 TCP 和 UDP 的说法正确的是( )。

A. TCP 保留应用每次发送的消息边界

B. UDP 默认提供按序可靠传输

C. TCP 通过确认、序号和重传等机制提供可靠字节流

D. UDP 一定比 TCP 在所有应用中更快

答案:C。 TCP 是字节流,不保留消息边界;UDP 默认不提供可靠有序传输;实际性能取决于场景和实现。

练习 2

为什么 HTTP 接口需要设计幂等性?

答案: 网络超时可能发生在服务端执行成功但响应未返回的阶段,调用方无法判断结果,重试会造成重复创建或重复扣款。通过幂等键、唯一约束、状态记录和重复请求返回原结果,可以让安全重试成为可能。

练习 3

多层重试为什么会导致请求量放大?应如何治理?

答案: 同一个失败请求经过客户端、网关和服务内部多次重试,重试次数会叠加甚至相乘,进一步消耗线程、连接和队列资源。治理方式包括统一重试责任、端到端超时预算、指数退避和抖动、最大次数、幂等、熔断、限流、舱壁和降级。

十一、论文素材

在分布式系统通信设计中,我按照应用、传输、网络和链路分层分析端到端路径,明确接口的数据格式、幂等语义、超时预算、重试边界和安全要求。针对关键交易使用可靠传输、请求编号和状态查询,针对实时数据采用适当的低延迟通信方式;通过连接复用、服务发现、负载均衡、限流、熔断和背压保护下游。上线后持续监控 P95/P99 延迟、丢包、重试率、连接池等待、队列长度和错误码,并通过网络分区与服务降级演练验证故障恢复能力。

论文中写网络协议时,要把协议机制与业务结果联系起来:连接管理影响资源,超时影响并发,重试影响负载,TLS 影响安全和性能,DNS 与发现影响切换。这样才能体现架构设计而非网络名词背诵。

十二、今日复盘

  1. 协议的语法、语义和时序分别是什么?
  2. 为什么网络协议采用分层和封装?
  3. IP、端口、域名和连接分别解决什么问题?
  4. TCP 为什么是字节流?应用如何处理消息边界?
  5. TCP 与 UDP 如何选择?
  6. HTTP 接口为什么要定义状态码、业务错误码和幂等语义?
  7. DNS 缓存和服务发现缓存有什么收益与风险?
  8. 超时和重试如何导致级联故障?

本节核心记忆句是:网络协议提供的是通信契约,真正的系统可靠性还需要应用层的幂等、超时、重试、限流、熔断和降级。架构师要从端到端路径看协议,把每一层的能力、代价和故障传播边界设计清楚。