为什么我不能超过32k或65k TIME-WAIT连接?

我一直在试图调整我们的Ubuntu 14.04 LTS Web服务器实例,托pipeWeb应用程序和反向代理Nginx,以便尽可能多地处理给定的硬件请求。 这是一个具有8x vCPU的c4.2xl EC2实例。

我从办公室机器上运行以下两个基准testing工具(不是同时):

wrk -c1000 -d2m -t8 --timeout 90 --latency http://api.mysite.com/2/ping # or ab -k -n 100000 -c 1000 http://api.mysite.com/2/ping 

我所看到的是通过运行ss -tan | wc -l ss -tan | wc -lTIME-WAIT我总是最多可以连接65.5k个连接

我的操作系统设置是:

  • net.ipv4.ip_local_port_range value="15000 65000"
  • /etc/security/limits.conf有“www-data hard nofile 100000”
  • /etc/pam.d/common-session*更新为上面的内容

nginx的设置是:

  • worker_processes auto; # will result in 8 on this machine

events { worker_connections 8192; multi_accept on; use epoll; }

在上面的代理到nginx的API是低于,​​用于获得不同的TCP四联组的最大值,这意味着我几乎永远不会用完临时端口在nginx – >应用程序:

upstream my_api { server 127.0.0.1:3004; server 127.0.0.2:3004; server 127.0.0.3:3004; [...] }

我遇到类似的问题,我的m3.large实例,而不是65k我最大在32k。 两者的区别在于前者有2vCPU,后者有8个,前者有7.5GB内存,后者有15GB。

在这篇文章中描述了一个类似的问题( 扩展超过65k的打开文件(TCP连接) ),但似乎并不适用于我的情况,因为在我的较小的实例上, vm.max_map_count是65530,但它永远不会超过32k TIME-WAIT连接。

我认为最初的限制是#进程*#工作者,但是在较小的情况下,即使我将每个进程的工人数提高到25k,也仍然只能达到32k,但事实并非如此。

我不确定这个时候要调整什么,我不清楚这些硬性约束可能来自哪里。 可以在这里使用一些帮助。

有趣的是,当TIME-WAIT达到这个“极限”时,我没有看到这两台机器之间的连接最终被拒绝。 有可能套接字队列在后台被填满,客户端只是重新尝试再次build立连接,这就是为什么我没有看到任何永久失败。

更新:

在一个c4.8xlarge的实例中,我可以在TIME-WAIT中使用相同的部署configuration来达到262k个连接。 甚至将nginx工作者的数量限制为1也不会改变它。 仍然不确定这里会有什么不同。

更新2:

我强烈怀疑这与不同的实例都有不同的net.ipv4.tcp_max_tw_buckets值,从我可以告诉匹配完全符合我看到的模式。

看看net.ipv4.netfilter.ip_conntrack_max可调参数。 有关更多信息,您可以阅读此ServerFault文章

源计算机上的源端口已用完。

为了识别您需要的连接:源IP,源端口,目标IP和目标端口。 由于源IP,目标IP和目标端口在testing中始终相同,因此只有一个variables:源端口。 你的TCP / IP堆栈不能处理多于64K的不同源端口(实际上less一点)。

从单一点进行压力testing绝不是一个好主意,但是您可以通过启用net.ipv4.tcp_tw_recycle重新使用处于TIME_WAIT状态的端口来挤压这一点,但是由于端口的重复使用可能会导致麻烦。