为什么数据位于Send-Q? TCP会话冻结

问题

我为20-50个用户运行一个IRC服务器。 我们有时会遇到邮件没有及时到达的问题。 在一些数据包捕获之后,我们确定消息位于服务器的“Send-Q”中。 当一个消息没有到达时,我会看看“netstat -ct”输出,看到这样的东西:

Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 1756 ubuntu:ircd 10.8.1.7:63602 ESTABLISHED

有时如果等待几分钟,Send-Q将变为0,并且消息将被传递,有时客户端超时。 我的问题是,为什么不传递信息? 是什么让他们坐在Send-Q这么久?

sshd也performance出类似的行为,我的ssh会话有时会冻结,有时会退出。

背景

不知道这里的基础设施是否可能与问题有关,所以这里是这样的:这些客户端在Windows 7上与OpenVPN连接。 OpenVPN服务器在PFSense上,IRC服务器在连接到PFSense的本地(NAT'd)LAN上。 我有一个防火墙规则,允许客户端与服务器上的6667通话。

调查…

延迟/损失 – 看起来不错。 不是有史以来最好的链接,但我认为这将适用于IRC和SSH。 这是从我的客户端到服务器的一个ping,这是我的IRC和SSH间歇悬挂:

 Ping statistics for 10.8.5.2: Packets: Sent = 4478, Received = 4460, Lost = 18 (0% loss) 

以毫秒为单位的近似往返时间:最小= 17.2毫秒,最大= 273.4毫秒,平均= 32.3毫秒

MSS / MTU问题 – MTU似乎没有问题 。 OpenVPN的mtu-test在我的客户端上说:

 Thu Dec 03 12:41:21 2015 NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[1589,1589] remote->local=[1589,1589] 

…这是我的手动testing:

 > ping -f -l 1472 10.8.5.2 Pinging 10.8.5.2 with 1472 bytes of data: Reply from 10.8.5.2: bytes=1472 time=23ms TTL=63 > ping -f -l 1473 10.8.5.2 Pinging 10.8.5.2 with 1473 bytes of data: Packet needs to be fragmented but DF set. 

带宽/吞吐量 – 做了一些iperftesting,以确保没有吞吐量问题。 再次,看起来不错,

 iperf -c 10.8.5.2 ------------------------------------------------------------ Client connecting to 10.8.5.2, TCP port 5001 TCP window size: 63.0 KByte (default) ------------------------------------------------------------ [ 3] local 10.8.0.23 port 18587 connected with 10.8.5.2 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 26.0 MBytes 21.8 Mbits/sec 

谢谢,任何帮助理解“Send-Q”或更具体的想法关于这个问题将不胜感激。 让我知道如果我可以在这里提供更多的信息。

更新

发现我实际上有大量的数据包丢失。 来自客户端 – > VPN的ping没有显示这一点,但从VPN->客户端使用fping时非常明显。 我注意到这只是Windows客户端,重新安装最新的OpenVPN客户端似乎已经修复了损失。 它可能与通过磁盘映像安装的OpenVPN TAP适配器有关。 每台机器手动安装似乎解决了这个问题。

当应用程序将其写入本地内核TCP堆栈时,数据将进入发送队列。 当对方的TCP栈确认接收到数据时,数据从发送队列中被移除。 如果他们坐在发送队列中,这意味着您的IRC服务器代码已经将它们发送到您的内核,但连接的另一端还没有确认它们。 这可能是因为他们还没有发送。 这可能是由服务器带宽限制或服务器性能限制造成的,但最常见的原因是对方没有像服务器发送数据一样快速接收数据。