Node.js 在大量并发连接中苦苦挣扎

标签 node.js ubuntu tcp apachebench sysctl

我正在开发一个有点不寻常的应用程序,其中 10,000 个客户端被精确地定时所有尝试一次提交数据,每 3 分钟左右。这个“ab”命令相当准确地模拟了现实世界中的一个弹幕:

ab -c 10000 -n 10000 -r "http://example.com/submit?data=foo"

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

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

当 Node 正常处理请求时,CPU 使用率通常在 50-70% 左右。在挂起期间,CPU 使用率达到 100%。有时它保持在 0 附近。在不稳定的 CPU 响应和它似乎与实际连接数(仅完成百分比)无关的事实之间,我不怀疑垃圾收集器。

我试过在本地主机和远程服务器上运行“ab”——效果相同。

我怀疑与 TCP 堆栈有关,可能涉及关闭连接,但我的配置更改均无济于事。我的改变:

  • ulimit -n 999999
  • 当我 listen() 时,我将 backlog 设置为 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

我还注意到我倾向于在内核日志中获取此消息:

TCP: Possible SYN flooding on port 80. Sending cookies.  Check SNMP counters.

我对这个消息感到困惑,因为 TCP 积压队列应该足够深,不会溢出。如果我禁用同步 cookie,“发送 cookie”会转到“断开连接”。

我推测这是某种 linux TCP 堆栈调整问题,我已经阅读了我在网上能找到的所有内容。我尝试过的一切似乎都不重要。有什么建议吗?

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

最佳答案

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

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

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

关于Node.js 在大量并发连接中苦苦挣扎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12022815/

相关文章:

javascript - 在 Firebase 云函数中哪里放置初始化代码?

javascript - 安装 yeoman 的问题

node.js - now.js 如何在没有浏览器(简单客户端)的情况下获取 'now' 对象?

python - ModuleNotFoundError : No module named 'jupyter_core'

Android令人沮丧的网络错误

javascript - 返回在循环中调用的回调结果的串联

python - 如何卸载 setuptools python

javascript - 无法解析主机 github.com

TCP连接池

sockets - Wireshark 和数据长度