网络 I/O 优化
网络 I/O 是分布式系统的生命线。一次网络请求可能涉及多次往返、数据包组装、拥塞控制等环节。理解并优化网络 I/O,是提升系统性能的关键。
Nagle 算法
Nagle 算法是 TCP 协议的一个特性,目的是减少小包数量,提高网络效率。
算法原理
Nagle 算法会缓存小数据包,直到收到 ACK 或缓冲区满了才发送:
问题:对于低延迟应用(如 RPC),等待 ACK 会增加延迟。
禁用 Nagle
Netty
适用场景
TCP_NODELAY 与延迟
启用 Nagle 算法后,TCP 会等待数据积累到一定量再发送:
对于需要低延迟的场景:
SO_SNDBUF 与 SO_RCVBUF
TCP 套接字有发送缓冲区和接收缓冲区:
缓冲区大小调优
设置缓冲区大小
适用场景
系统限制
SO_REUSEADDR:地址复用
TIME_WAIT 状态下,端口无法立即重用:
启用地址复用
Netty
场景:服务器重启时,如果端口还在 TIME_WAIT 状态,可以立即重新绑定。
TCP 保活(SO_KEEPALIVE)
TCP 保活用于检测连接是否还存活:
启用
保活参数
连接复用(HTTP/1.1 Keep-Alive)
HTTP/1.1 默认启用 Keep-Alive,一个 TCP 连接可以发送多个请求:
连接复用与 HTTP/2
HTTP/2 通过多路复用,在一个连接上并行处理多个请求:
网络 I/O 调优检查清单
JVM 参数
TCP 参数
文件描述符
本章小结
网络 I/O 优化的核心要点:
- Nagle 算法:低延迟场景禁用,高吞吐场景启用
- 缓冲区大小:大文件传输用大缓冲区,高并发用小缓冲区
- 地址复用:服务器重启场景启用 SO_REUSEADDR
- TCP 保活:检测空闲连接,及时清理
延伸思考
为什么现代 RPC 框架(如 gRPC)默认禁用 Nagle?
因为 RPC 的特点是:
- 请求频繁但数据量小
- 延迟敏感(每次 RPC 都在等待)
- 吞吐量要求高
在这些场景下,Nagle 的"合并小包"反而会增加不必要的延迟。禁用 Nagle 可以让每个 RPC 请求立即发送,虽然会发送更多小包,但换来了更低的延迟。