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

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

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

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

我可以监控接受队列的长度或溢出数量吗?柜台是否暴露在外?

答案1

要检查队列是否溢出,请使用 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

系统挖掘将在每个系统调用结束时提供一些此类信息accept作为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

答案3

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

net.ipv4.tcp_max_syn_backlog = 4096

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

另请确保以下各项未设置为 1:

net.ipv4.tcp_abort_on_overflow = 0

否则如果积压溢出肯定会丢包。

sysctl -a | grep backlog您可以使用或轻松检查值sysctl -a | grep overflow

此外,您可以在下面找到“已删除”标签

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 服务器以更快地接受放置在“总聚合”队列上的连接。

相关内容