我一直在阅读关于Linux上TCP实现的文章,有些搞不清楚,net.ipv4.tcp_max_syn_backlog
和net.core.somaxconn
以及作为listen()
系统调用参数的backlog
之间有什么区别,它们之间的联系是什么。
注:我想要针对内核版本4.15的解释,因为我发现在这个主题上较老和较新的内核之间存在一些差异。
我一直在阅读关于Linux上TCP实现的文章,有些搞不清楚,net.ipv4.tcp_max_syn_backlog
和net.core.somaxconn
以及作为listen()
系统调用参数的backlog
之间有什么区别,它们之间的联系是什么。
注:我想要针对内核版本4.15的解释,因为我发现在这个主题上较老和较新的内核之间存在一些差异。
sysctl是一个API。因此,您可以阅读适当版本的Linux内核文档:
tcp_max_syn_backlog - INTEGER
Maximal number of remembered connection requests, which have not
received an acknowledgment from connecting client.
The minimal value is 128 for low memory machines, and it will
increase in proportion to the memory of machine.
If server suffers from overload, try increasing this number.
somaxconn - INTEGER
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
Defaults to 128. See also tcp_max_syn_backlog for additional tuning
for TCP sockets.
tcp_max_syn_backlog
代表SYN_RECV
队列中连接的最大数量。也就是说,当您的服务器收到SYN并发送SYN-ACK但尚未收到ACK时。这是一种称为“请求套接字”的单独队列,在代码中称为reqsk
(即不完全的套接字,“请求套接字”占用更少的内存)。在此状态下,我们可以节省一些内存,并且如果ACK不到达,则不需要分配完整的套接字。该队列的值受到影响(请参见此帖子)通过listen()
的backlog
参数并由内核中的tcp_max_syn_backlog
限制。
somaxconn
代表ESTABLISHED
队列的最大大小。这是另一个队列。回想一下先前提到的SYN_RECV
队列-您的服务器正在等待来自客户端的ACK。当ACK到达时,内核会从“请求套接字”中大致地创建完整的套接字,并将其移动到已建立队列中。然后,您可以在此套接字上执行accept()
。该队列也受listen()
的backlog
参数的影响,并由内核中的somaxconn
限制。
sk_acceptq_is_full
和inet_csk_reqsk_queue_is_full
将与通过listen()
调用设置的sk->sk_max_ack_backlog
进行比较。 - red0ctlisten()
系统调用中,backlog参数被截断为somaxconn值。因此,somaxconn值不应超过65535(USHRT_MAX)"*. 添加了链接。如果我的回答有帮助,请标记为已接受。 - red0ct