31.7. 识别应用程序读套接字缓冲区瓶颈
如果 TCP 应用程序没有频繁清除读套接字缓冲区,则性能可能会会受到影响,数据包可能会丢失。Red Hat Enterprise Linux 提供了不同的工具来识别这些问题。
31.7.1. 识别接收缓冲区崩溃和修剪
当接收队列中的数据超过接收缓冲区大小时,TCP 堆栈会尝试通过从套接字缓冲区中删除不必要的元数据来释放一些空间。此步骤被称为崩溃。
如果崩溃无法为额外的流量释放足够的空间,则内核会修剪到达的新数据。这意味着内核从内存中删除数据,数据包丢失。
为避免崩溃和修剪操作,请监控 TCP 缓冲区是否在服务器上发生了崩溃和修剪,在这种情况下,调整 TCP 缓冲区。
流程
使用
nstat
程序查询TcpExtTCPRcvCollapsed
和TcpExtRcvPruned
计数:# nstat -az TcpExtTCPRcvCollapsed TcpExtRcvPruned #kernel TcpExtRcvPruned 0 0.0 TcpExtTCPRcvCollapsed 612859 0.0
等待一些时间,然后重新运行
nstat
命令:# nstat -az TcpExtTCPRcvCollapsed TcpExtRcvPruned #kernel TcpExtRcvPruned 0 0.0 TcpExtTCPRcvCollapsed 620358 0.0
与第一次运行相比,如果计数的值增加了,则需要调整:
-
如果应用程序使用
setsockopt (SO_RCVBUF)
调用,请考虑将其删除。使用这个调用,应用程序仅使用调用中指定的接收缓冲区大小,并关闭套接字自动调整其大小的能力。 -
如果应用程序没有使用
setsockopt (SO_RCVBUF)
调用,请调整 TCP 读套接字缓冲区的默认值和最大值。
-
如果应用程序使用
显示接收积压队列(
Recv-Q
):# ss -nti State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192.0.2.1:443 192.0.2.125:41574 :7,7 ... lastrcv:543 ... ESTAB 78 0 192.0.2.1:443 192.0.2.56:42612 :7,7 ... lastrcv:658 ... ESTAB 88 0 192.0.2.1:443 192.0.2.97:40313 :7,7 ... lastrcv:5764 ... ...
多次运行
ss -nt
命令,每次运行之间等待几秒钟。如果输出在
Recv-Q
列中只出现一次高值,则应用程序介于两个接收操作之间。但是,如果Recv-Q
中的值在lastrcv
持续增长期间保持不变,或者Recv-Q
随着时间的推移不断增加,则以下几个问题可能是原因:- 应用程序不会检查其套接字缓冲区是否足够。有关如何解决这个问题的详细信息,请联络应用程序厂商。
应用程序没有获得足够的 CPU 时间。要进一步调试这个问题:
显示应用程序运行在哪个 CPU 核上:
# ps -eo pid,tid,psr,pcpu,stat,wchan:20,comm PID TID PSR %CPU STAT WCHAN COMMAND ... 44594 44594 5 0.0 Ss do_select httpd 44595 44595 3 0.0 S skb_wait_for_more_pa httpd 44596 44596 5 0.0 Sl pipe_read httpd 44597 44597 5 0.0 Sl pipe_read httpd 44602 44602 5 0.0 Sl pipe_read httpd ...
PSR
列显示当前进程被分配给哪个 CPU 核。- 识别在同一核上运行的其他进程,并考虑将它们分配到其他核。
其他资源