Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js struggling with lots of concurrent connections

I'm working on a somewhat unusual application where 10k clients are precisely timed to all try to submit data at once, every 3 mins or so. This 'ab' command fairly accurately simulates one barrage in the real world:

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

I'm using Node.js on Ubuntu 12.4 on a rackspacecloud VPS instance to collect these submissions, however, I'm seeing some very odd behavior from Node, even when I remove all my business logic and turn the http request into a no-op.

When the test gets about 90% done, it hangs for a long period of time. Strangely, this happens consistently at 90% - for c=n=10k, at 9000; for c=n=5k, at 4500; for c=n=2k, at 1800. The test actually completes eventually, often with no errors. But both ab and node logs show continuous processing up till around 80-90% of the test run, then a long pause before completing.

When node is processing requests normally, CPU usage is typically around 50-70%. During the hang period, CPU goes up to 100%. Sometimes it stays near 0. Between the erratic CPU response and the fact that it seems unrelated to the actual number of connections (only the % complete), I do not suspect the garbage collector.

I've tried this running 'ab' on localhost and on a remote server - same effect.

I suspect something related to the TCP stack, possibly involving closing connections, but none of my configuration changes have helped. My changes:

  • ulimit -n 999999
  • When I listen(), I set the backlog to 10000

Sysctl changes are:

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

I have also noticed that I tend to get this msg in the kernel logs:

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

I'm puzzled by this msg since the TCP backlog queue should be deep enough to never overflow. If I disable syn cookies the "Sending cookies" goes to "Dropping connections".

I speculate that this is some sort of linux TCP stack tuning problem and I've read just about everything I could find on the net. Nothing I have tried seems to matter. Any advice?

Update: Tried with tcp_max_syn_backlog, somaxconn, netdev_max_backlog, and the listen() backlog param set to 50k with no change in behavior. Still produces the SYN flood warning, too.

like image 533
stickfigure Avatar asked Aug 18 '12 22:08

stickfigure


People also ask

How many concurrent connections can Nodejs handle?

JS uses a single thread with an event-loop. In this way, Node can handle 1000s of concurrent connections without any of the traditional detriments associated with threads.

Is node js still relevant 2021?

js dead? The short answer is “NO.” The long answer is, “NO, it's not dead, and it probably will never die.” Node. js is just as relevant to coding in 2021 and beyond, even if the hype around it has stabilized slightly.

Is node js the best platform for CPU heavy applications Why?

js for CPU-intensive operations; in fact, using it for heavy computation will annul nearly all of its advantages. Where Node really shines is in building fast, scalable network applications, as it's capable of handling a huge number of simultaneous connections with high throughput, which equates to high scalability.


1 Answers

Are you running ab on the same machine running node? If not do you have a 1G or 10G NIC? If you are, then aren't you really trying to process 20,000 open connections?

Also if you are changing net.core.somaxconn to 10,000 you have absolutely no other sockets open on that machine? If you do then 10,000 is not high enough.

Have you tried to use nodejs cluster to spread the number of open connections per process out?

like image 142
Andrew T Finnell Avatar answered Sep 28 '22 08:09

Andrew T Finnell