- Millions of active WebSockets with Node.js
- Alex Hultman
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: Mirosalva
- Proofreader: Portandbridge, Sunui
A large number of WebSocket services are available using only a consumer laptop and some Wifi resources
With the newly released TypeScript Web services project uWebSockets. Js, we see not only improved performance but also improved memory utilization. This is especially true for Node.js users, so for demonstration purposes I wanted to do a large scale test in a real-world environment.
We plan to use my six-year-old laptop with 8GB of ram and a 72Mbit Wifi adapter (that’s the speed of the Internet connection). It also has a 1Gbit Ethernet adapter that we can use later. All configurations are consumer grade, with no hardware upgrades after purchase in 2013. This laptop will run Node.js with uWebSockets. Js v15.1.0 installed.
The first thing we need to do some Linux system configuration, main is need to change the file/etc/security/limits the conf (path to the file on your system may be different, I am here with Ubuntu version 18.04) to improve the largest open file number of restrictions. Add the following lines:
* soft nofile 1024000
* hard nofile 1024000
Copy the code
Then we need to set some other variables (again, your path may be different) :
sudo sysctl net.ipv4.tcp_tw_reuse=1
sudo sysctl fs.file-max=1024000
Copy the code
Then you need to configure about 50 IP addresses in a certain network segment. For my Wifi adapter, I added this line of configuration:
for i in{135.. 185};doSudo IP addr add 192.168.0.$i/24 dev wlp3s0; done
Copy the code
Theoretically, each IP address has a 65K connection limit, but in practice the limit is usually around 20K, so we use multiple addresses and each address supports 20K connections (50 x 20 thousand = 1 million).
I then run the web service as root using the command sudo -i, which is followed by ulimit -n 1024000, Then do the same for node examples/ websocket.js (in the uWebSockets.
It really is. A similar configuration is performed on the client, but multiple IP addresses do not need to be set. The client computer runs a single-threaded C client written by uSockets. The source code for this test is open source, and the client code is located in the uWebSockets/benchmarks folder “scale_test.c”. You may need to make some minor changes to your own implementation.
The number of WebSocket connections will take a few minutes to reach a million, and if we wanted to make improvements we could increase the number of connections per batch and clients using multiple threads (and so on), but that doesn’t matter what we’re interested in on the server side. The server runs on a single thread and has low CPU usage during and after the connection phase.
First, let’s talk about 5K closed connections. UWebSockets. Js is configured to discard and kill all WebSocket connections that have been idle for more than 60 seconds. “IdleTimeout” is used, which means we need to actively send and receive a WebSocket message every 60 seconds for every million WebSocket connections.
You can see the peak traffic associated with ping messages in the network graph above. At least 16.7K WebSocket messages need to reach the server per second — that’s when we started closing connections.
Obviously we don’t meet that standard very well with Wifi. We did lose some connections, but it was cool to have 995K WebSocket connections on a WiFi network with no fancy specs!
Server CPU usage remained in the 0-2% range, user-controlled space memory usage was about 500MB and overall system-wide memory usage was about 4.7GB. There has never been a server surge in CPU usage or memory usage, it has remained completely stable.
All right! So let’s take out the big kill – Ethernet. We connected the server and client to a 1Gbit consumer router and re-ran the test:
The result was stable service performance and no lost connections, WiFi network stability was poor but Ethernet performed well. To make sure everything was stable, I kept the client and server running for an hour so that no connections were lost, and then about 120 million WebSocket messages (16.7K * 60 * 60 * 2) :
Everything is stable and working well. In fact, I’m writing this on a laptop running the service, and the number of closed socket connections is always zero, and the system is responsive. The service keeps the connection going even if I start a simple game.
At this point we have implemented a very cool proof-of-concept scenario. Part of this is due to stable Ethernet connections, but of course it also relies heavily on server-side software. No other Node.js stack can achieve this feat — none of them has the lightweight and high performance features to sustain so many WebSocket connections on a laptop. You can stop the swap when the system becomes unresponsive and stop getting the ping result as seen below:
Using uWebSockets. Js, we could run hundreds of thousands of WebSocket connections on this laptop, but over a million regular connections would require recompiling the Linux kernel with different limitations, which is why we used it as a boundary value.
We’re not going to go into the underlying embedded C development here, and I think that’s a wise choice. Just start a new application instance, a new laptop, and continue to expand your problem that way.
If you are interested in this software stack, have I/O scalability issues, or want to avoid many common pitfalls, be sure to contact us and we can discuss the issues on a company-to-company basis.
Thanks for reading!
If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.