34.7. 识别应用程序读套接字缓冲区瓶颈
如果 TCP 应用程序无法频繁清除读套接字缓冲区,则性能可能会受到影响,数据包可能会丢失。Red Hat Enterprise Linux 提供了不同的工具来识别此类问题。
34.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 httpdPSR
列显示进程当前分配给的 CPU 核。