Day03-05|2.3.5 网络协议
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 与发现影响切换。这样才能体现架构设计而非网络名词背诵。
十二、今日复盘
- 协议的语法、语义和时序分别是什么?
- 为什么网络协议采用分层和封装?
- IP、端口、域名和连接分别解决什么问题?
- TCP 为什么是字节流?应用如何处理消息边界?
- TCP 与 UDP 如何选择?
- HTTP 接口为什么要定义状态码、业务错误码和幂等语义?
- DNS 缓存和服务发现缓存有什么收益与风险?
- 超时和重试如何导致级联故障?
本节核心记忆句是:网络协议提供的是通信契约,真正的系统可靠性还需要应用层的幂等、超时、重试、限流、熔断和降级。架构师要从端到端路径看协议,把每一层的能力、代价和故障传播边界设计清楚。