如何监视接受队列的长度?


9

我有一个假设:有时TCP连接到达的速度比我的服务器可以到达的速度快accept()。他们排队直到队列溢出,然后出现问题。

我如何确认这种情况正在发生?

我可以监视接受队列的长度或溢出次数吗?某处有柜台吗?


您正在寻找netstat
聪桂

据我所知,netstat仅显示发送和接收队列的长度,这与接受队列的长度不同。
菲尔·弗罗斯特

是的,默认情况下未显示。man netstat | less +/Flags
佐藤桂

我不确定这些标志如何告诉我接受队列的长度-实际上,TCP连接netstat似乎根本没有显示Flags。从一个小的测试,它看起来像连接显示为ESTABLISHEDnetstat,即使我尝试打开一个过程,它的连接listen(),但从来没有accept()
菲尔·弗罗斯特

正确,查看源代码,这些标志似乎是针对UNIX套接字的。对于TCP,您可以算一下SYN_RECV。除此之外,没有其他队列。我想可以告诉内核由于过多的半开连接而以某种方式记录丢弃的数据包,但是自从我研究与Linux联网以来已有十多年了,所以我不知道该怎么做。附带说明:您不是在等待accept()完成其工作,而是在等待ACKs从连接的主机到达以完成连接。
佐藤桂

Answers:


3

要检查队列是否溢出,请使用netstat或nstat

[centos ~]$ nstat -az | grep -i listen
TcpExtListenOverflows           3518352            0.0
TcpExtListenDrops               3518388            0.0
TcpExtTCPFastOpenListenOverflow 0  0.0

[centos ~]$ netstat -s | grep -i LISTEN
    3518352 times the listen queue of a socket overflowed
    3518388 SYNs to LISTEN sockets dropped

参考:https : //perfchron.com/2015/12/26/investigating-linux-network-issues-with-netstat-and-nstat/

要监视队列大小,请使用ss命令并查找SYN-RECV套接字。

$ ss -n state syn-recv sport = :80 | wc -l
119

参考:https : //blog.cloudflare.com/syn-packet-handling-in-the-wild/


2

Sysdig将在每个acceptsyscall 的结尾提供一些此类信息作为queuelen参数。它还将队列的长度显示为queuemax

7598971 21:05:30.322229280 1 gunicorn (6451) < accept fd=13(<4t>127.0.0.1:45882->127.0.0.1:8003) tuple=127.0.0.1:45882->127.0.0.1:8003 queuepct=0 queuelen=0 queuemax=10

据我所知,它没有提供确切知道队列何时或多少次溢出的机制。将其与定期监视collectd或类似监视相集成将很麻烦。


0

您正在寻找的是sysctl -a命令的输出中的条目,例如:::

net.ipv4.tcp_max_sync_backlog = 4096

在上述示例中,SYN状态连接的积压最大为4096。您可以根据服务器中的RAM数量来增加积压。我认为32K积压是调整重载Web服务器的良好开端。

还要确保以下内容未设置为一(1)::

net.ipv4.tcp_abort_on_overflow = 0

否则,如果积压溢出,肯定会丢弃数据包。

您可以轻松地通过检查

“ sysctl -a | egrep积压”

“ sysctl -a | egrep溢出”

此外,您还可以在

“ ifconfig -a”

命令的输出。这显示了每个接口丢弃了多少个数据包以及其他数据和错误等。

对于记录丢弃的数据包,RHEL 7上有一个付费专栏文章:

https://access.redhat.com/solutions/1191593

为了进一步研究,您可以阅读:

http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html

它按照史蒂文的《 TCP / IP说明》在此处声明:

“队列限制适用于[…]未完成的连接队列[…]上的条目数和[…]已完成的连接队列[…]上的条目数之和。”

因此还指出:

“完成的连接队列几乎总是空的,因为当将条目放置在此队列上时,服务器的接受接受的调用将返回,并且服务器将完成的连接从队列中移出。”

因此,accept队列可能看起来完全是空的,您将不得不调整您的Web Apache服务器(在这种情况下,可能是这样)以更快地接受放置在“总计”队列上的连接。


尽管这里似乎有一些有用的信息,但我不确定它是否能回答问题。如果我问:“一次来这个礼堂的人数最多是多少?”,而您指着墙上能显示最大人数的标志,您还没有回答这个问题。
斯科特,

确实,我在寻找队列的当前长度,而不是队列的最大长度。
Phil Frost

3
它应该是tcp_max_syn_backlog,而不是您回答中的
tcp_max_SYNC_backlog

是的...当您尝试更改它时,StackOverflow会为您提供延迟的错误消息:“编辑必须至少包含6个字符;本文中还有其他改进之处吗?”
Aaron C. de Bruyn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.