F5社区-F5技术交流中心

NGINX TCP 传输队列调优

2022-06-23 18:52:06

纪柯凌

PHPWord

 

  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

Login

手机号
验证码
© 2019 F5 Networks, Inc. 版权所有。京ICP备16013763号-1