跳到正文
Elaine Blog
返回

TCP、UDP、拥塞控制与连接故障

网络与 I/O

TCP 保证的是“连接存续期间按序交付字节”,不是请求一定成功。进程崩溃、网络分区、超时后的重复执行,都需要应用协议处理。 本篇先分清 TCP 与 UDP,再建立连接故障的判断顺序。

Table of contents

Open Table of contents

TCP 和 UDP 提供什么

TCP 是面向连接的可靠字节流。发送方给出的两次 write,接收方可能一次读完,也可能分多次读到,因此应用必须定义消息边界。 TCP 使用序号、确认、校验和与重传来处理丢包和乱序。

UDP 发送独立数据报,不建立 TCP 式连接,也不保证送达、顺序或唯一性。它保留数据报边界,协议可在用户态按需求增加确认、重传或前向纠错。 “UDP 更快”不是无条件结论;可靠性逻辑只是从内核 TCP 移到了上层协议。

握手、关闭与常见状态

三次握手让双方确认收发能力并同步初始序号。关闭是双向的:一端不再发送,不代表另一端已经发送完,因此通常需要四次报文完成。

排障常见状态:

状态含义先检查什么
LISTEN服务端等待连接地址、端口、防火墙
SYN-SENT已发起连接,等待响应路由、丢包、对端监听
ESTABLISHED连接已建立不等于应用健康
CLOSE-WAIT对端已关闭,本地未关闭应用是否遗漏 close
TIME-WAIT主动关闭方等待旧报文消失是否短连接过多

状态数量必须结合连接创建速率、持续时间和业务流量判断,不能看到 TIME-WAIT 就直接改内核参数。

流量控制和拥塞控制不是一回事

流量控制保护接收方:接收窗口告诉发送方还有多少缓冲空间。拥塞控制保护网络:发送方根据确认、丢包和时延推测路径容量,调整在途数据。 两者都会让发送变慢,但瓶颈位置不同。

队头阻塞是“前面的缺失数据阻挡后续数据交付”。TCP 必须按序交付,所以一个丢失段会影响同连接后续字节;HTTP/2 多路复用解决了 HTTP 层队头问题, 却仍运行在 TCP 上。HTTP/3 基于 QUIC,把多个流的丢包影响隔离开。

超时后结果仍可能成功

客户端超时只表示“在截止时间前没收到结果”,无法证明服务端没有执行。支付、下单等写操作需要幂等键:同一业务请求即使重试,也只能产生一次效果。

重试应同时满足:错误可恢复、操作幂等、剩余截止时间足够,并使用退避和随机抖动。无上限立即重试会在故障时制造更多流量。

排障顺序

  1. 确认服务是否监听正确地址和端口;
  2. 检查 DNS、路由、防火墙和负载均衡健康检查;
  3. 对比连接、重传、往返时延和窗口指标;
  4. 检查应用读取、写入和关闭是否有截止时间;
  5. 最后才评估连接池与内核参数。

Connection resetBroken pipe 都只说明连接某处被关闭,必须结合关闭方、时间线和应用日志解释。

下一步

阅读BIO、NIO、直接内存与零拷贝,观察 Java 程序怎样读写这条字节流。


分享这篇文章:

上一篇
一次网页请求经历了什么:从域名到应用线程
下一篇
BIO、NIO、直接内存与零拷贝