网络协议-TCP
TCP协议基础
1. TCP握手流程
2. TCP连接数
- TCP连接是由客户端IP地址与端口、服务器IP地址与端口4元素确定
- 由于IPv4地址长度是32位,端口长度是16位,故IP、端口都确定的服务器上能够支持的最大连接数是232+16
3. TCP层的有序字符流
- 在TCP上实现的多路复用,必然面临队头阻塞问题。HTTP2必须等完整的包返回才行,在网络不好的情况下丢包会阻断请求。所以,低网络下,HTTP2不如HTTP1.1。
- HTTP3基于UDP后没有了队头阻塞,但必须在QUIC Stream层重新实现有序字节流
- HTTP3的连接迁移功能通过Packet Header中的Connection ID实现
优化TCP协议的性能
1. 服务器建立连接的2个队列
2. 对抗SYN攻击 - accept连接队列满了
netstat -s | grep "SYNs to LISTEN": 调大队列;net.ipv4.tcp_syncookies = 1: 只能解决SYN半连接队列满了的问题,下次请求,不进入SYN半连接,只把进入的服务信息存到SYN Cookie,accept连接队列直接取SYN Cookie里的信息;net.ipv4.tcp_abort_on_overflow = 0: 暂时不响应,连接队列有空隙时,再处理;net.ipv4.tcp_abort_on_overflow = 1: 返回RST。
3. TCP Fast Open - 绕过TCP三次握手
- net.ipv4.tcp_fastopen = 3: 打开TCP Fast Open;
- 首次连接,客户端和服务端都打开TCP Fast Open,首次TCP连接,服务器生成Cookie,返回客户端,客户端存储Cookie;第二次连接,使用Cookie建立连接,减少TCP三次握手,提升连接速度。
4. 优化TCP的关闭连接的TIME-WAIT状态
- 主动关闭连接,会进入TIME-WAIT状态,TIME-WAIT状态会有2分钟的端口占用时间;
- 所以,需要减少TIME-WAIT状态中端口的数量。
- Linux下,net.ipv4.tcp_tw_reuse = 1
- 开启后,作为客户端时新连接可以使用仍然处于TIME-WAIT状态的端口
- 由于timestamp的存在,操作系统可以拒绝迟到的报文
- net.ipv4.tcp_timestamps = 1
- Linux下,net.ipv4.tcp_max_tw_buckets = 262144
- time_wait状态连接的最大数量
- 超出后直接关闭连接
5. TCP的Keep-Alive功能
优化长时间不发送消息的长连接
- Linux的tcp keepalive
- 发送心跳周期
- Linux: net.ipv4.tcp_keepalive_time = 7200
- 探测包发送间隔
- net.ipv4.tcp_keepalive_intvl = 75
- 探测包重试次数
- net.ipv4.tcp_keepalive_probes = 9
- 发送心跳周期