NGINX TCP 传输队列调优
2022-06-23 18:52:06
纪柯凌
TCP 处理连接调优
1、 只有一个队列,通过backlog参数调整( listen()系统调用的参数)。 一旦收到syn,队列保存连接信息,并返回syn+ack。 (SYN RECEIVED)
一旦收到ACK,服务端把保存的连接信息改变为ESTABLISED,等待应用accept()系统调用获得数据并清空。 (ESTABLISHED)
以上可以看到一个队列中的连接会有两个状态的可能,SYN RECEIVED / ESTABLISHED
2、 另一种实现是2个队列。 SYN Queue(又叫incomplete queue) 和 Accept Queue ( 又叫 complete connect queue ) 。
SYN Queue 存放的是状态为SYN RECEIVED的connection ;
Accept Queue 存放的是状态为 ESTABLISED的connection, 等待应用的 accept() system call 去获取连接。
历史上BSD使用的就是第一种方式, backlog直接调整队列深度。队列超过了新的tcp请求会直接丢弃。 (不会drop)
linux kernal 2.2 后使用第二种方式。半开队列 SYN Queue 的最大长度调整: /proc/sys/net/ipv4/tcp_max_syn_backlog ,系统内核层面的调整,所有应用共享
Linux TCP连接队列
半开队列 Syn queue: 服务端收到syn,把相关连接数据放到syns queue中,返回syn+ack包给客户端
全开队列 Accept queue: 一旦三次握手完成,如果accept queue没满,会把半开队列的连接数据复制到全开队列。 应用会通过accept()系统调用
持续从 accept queue中读取连接数据处理具体的后续连接。处理完毕就去掉accept queue中对应的连接数据。
上面的bind()、listen()、accept() 等等都是system call
如果accept queue队列满了,收到ACK,如何处理会根据 tcp_abort_on_overlfow 来决定 :
1、 /proc/sys/net/ipv4/tcp_abort_on_overflow = 1 , 则服务端会直接RST 连接。
2、如果没有设置overflow bit,服务端会忽略这个ACK包。 因为忽略了,所以服务端等待ACK超时后,会重传SYN+ACK , 并且根据设置的重传数进
入指数回退算法。(TCP RTO timeout 的重传触发激进的拥塞避免机制) /proc/sys/net/ipv4/tcp_synack_retries << 重传次数设置
配置全开队列和半开队列
几个参数
配置
tcp_max_syn_backlog 配置syn queue半开队列,因为是系统内核参数,所有应用共用。 /proc/sys/net/ipv4/tcp_max_syn_backlog
somaxconn 和 backlog 都会影响全开队列, somaxconn是内核参数, backlog是用户态的应用参数。 nginx默认511 。
所以单独配置某个参数都不行,要都配置,因为两个都有约束能力, 因此为 min(backlog,somaxconn) 。 建议配置一致。
(单纯配置backlog,但是用户态切到内核态的时候,依然收到限值。反之亦然。)
linux配置:
sudo sysctl -w net.core.somaxconn=4096
修改/etc/sysctl.conf
net.core.somaxconn = 4096
Nginx配置backlog:
server {
listen 80 backlog=4096;
}
队列查看
在系统中,正常接受的连接建立之后(TCP三次握手之后),会被置于监听socket的队列之中。 查看方式:netstat -Lan
netstat -Lan : -L查看监听队列情况 -n不做反解 -a显示所有socket
Local Address: socket监听的地址和端口
Listen: 监听socket的队列深度:
1st number of unaccepted connections
2nd number of unaccepted incomplete connections
3rd number of maximum queued connections
qlen: queue length 表还没有被accept() 处理的连接请求,这些连接请求都已经完成三次握手。说明是在全开队列中的connection数量
incqlen:incomplete queue length 半开队列深度, 表示还没有建立好连接,在syn queue半开队列中的连接数量。
maxqlen: max queue length ,最大队列深度。 超过后会discard new connect。(freeBSD可以容忍队列中未处理请求超过1.5倍的limit才
开始discard)
这里的maxqlen 是系统层面的accept queue 的最大队列深度。 min(backlog,somaxconn)
NGINX的TCP队列调优
nginx的队列调优,和应用相关的调整参数就是 用户态的 backlog。 (设置accept queue全开队列)
当然,因为系统层面的内核态的somaxconn 存在,两个都需要调整。 最好是一直。
·sudo sysctl -w net.core.somaxconn=4096
OR
编辑/etc/sysctl.conf
添加: net.core.somaxconn = 4096
server {
listen 80 backlog=4096; << backlog
# ...
}
发布评论 加入社群
相关文章

nginx和jwt
纪柯凌
2022-06-23 19:41:24 411

容器安全和linux capabilities
纪柯凌
2022-06-23 19:06:17 568

回复评论
发布评论