Node.js在很多并发连接上苦苦挣扎

sti*_*ure 7 ubuntu tcp apachebench sysctl node.js

我正在开发一个有点不同寻常的应用程序,其中10k客户正好计时,每隔3分钟左右一次尝试提交数据.这个'ab'命令相当准确地模拟了现实世界中的一个弹幕:

ab -c 10000 -n 10000 -r "http://example.com/submit?data=foo"
Run Code Online (Sandbox Code Playgroud)

我在Rackspacecloud VPS实例上使用Ubuntu 12.4上的Node.js来收集这些提交,但是,我看到Node的一些非常奇怪的行为,即使我删除了所有的业务逻辑并将http请求变为no-运.

当测试完成大约90%时,它会挂起很长一段时间.奇怪的是,这种情况一直发生在90% - 对于c = n = 10k,在9000; 对于c = n = 5k,在4500; 对于c = n = 2k,在1800.测试实际上最终完成,通常没有错误.但ab和节点日志都显示连续处理直到测试运行的大约80-90%,然后在完成之前长时间停顿.

当节点正常处理请求时,CPU使用率通常约为50-70%.在挂起期间,CPU上升到100%.有时它会保持在0附近.在不稳定的CPU响应和它看起来与实际连接数无关(只有%完成)的事实之间,我不怀疑垃圾收集器.

我试过在localhost和远程服务器上运行'ab' - 效果相同.

我怀疑与TCP堆栈有关的东西,可能涉及关闭连接,但我的配置更改都没有帮助.我的变化:

  • ulimit -n 999999
  • 当我listen()时,我将积压设置为10000

Sysctl的变化是:

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_orphans = 20000
net.ipv4.tcp_max_syn_backlog = 10000
net.core.somaxconn = 10000
net.core.netdev_max_backlog = 10000
Run Code Online (Sandbox Code Playgroud)

我也注意到我倾向于在内核日志中获得这个消息:

TCP: Possible SYN flooding on port 80. Sending cookies.  Check SNMP counters.
Run Code Online (Sandbox Code Playgroud)

我很困惑这个消息,因为TCP积压队列应该足够深,永远不会溢出.如果我禁用syn cookie,"发送cookie"将转到"删除连接".

我推测这是某种linux TCP堆栈调优问题,我已经阅读了我在网上可以找到的所有内容.我没有尝试过任何事情似乎很重要.有什么建议?

更新:尝试使用tcp_max_syn_backlog,somaxconn,netdev_max_backlog和listen()backlog参数设置为50k,但行为没有变化.仍然会产生SYN洪水警告.

And*_*ell 3

您是否在运行节点的同一台机器上运行 ab?如果没有,您有 1G 或 10G 网卡吗?如果是,那么您不是真的在尝试处理 20,000 个打开的连接吗?

另外,如果您要更改net.core.somaxconn为 10,000,那么该机器上绝对没有其他套接字打开?如果您这样做,那么 10,000 还不够高。

您是否尝试过使用nodejs集群来分散每个进程的打开连接数?