[译] 使用 Node.js 提供百万的活跃 WebSocket 连接 - 掘金

标签: | 发表时间:2019-04-23 19:55 | 作者:
出处:https://juejin.im

仅使用消费级笔记本和一些 Wifi 资源便可提供大量的 WebSocket 服务

通过最新发布的 TypeScript web 服务工程 uWebSockets.js,我们看到它带来的不仅有提升的性能,还有提升的内存利用率。对 Node.js 使用者尤其如此,所以为了演示我想在实际使用环境中开展大规模的测试。

我们计划使用我那购买了 6 年的笔记本电脑,它具有 8GB 运行内存和 72Mbit 速率的 Wifi 网络适配器(这是网络链接速度)的笔记本电脑。它还有一个 1Gbit 速率的以太网适配器,我们可以稍后使用。所有配置都是消费级的,在 2013 年购买后没有任何硬件升级。这个笔记本将运行安装了 uWebSockets.js v15.1.0 的 Node.js。

服务器硬件

我们首先需要做一些 Linux 系统的配置工作 —— 主要是需要通过修改文件 /etc/security/limits.conf(在你的系统上文件路径可能不同,我这里用的是 Ubuntu 18.04 版本)来提升最大打开文件数量的限制。添加如下几行:

      * soft nofile 1024000
* hard nofile 1024000复制代码

然后我们需要设置一些其他变量(同样的,你的路径可能不同):

      sudo sysctl net.ipv4.tcp_tw_reuse=1
sudo sysctl fs.file-max=1024000复制代码

然后你需要需要配置某一网段内的大约 50 个 IP 地址。对于我的 Wifi 适配器,我添加了这行配置:

      foriin{135..185};dosudo ip addr add 192.168.0.$i/24 dev wlp3s0;done复制代码

理论上,每个 IP 地址有 65k 个连接限制,但是实际上限值经常大约在 20k 左右,所以我们使用多个地址且使每个地址支撑 20k 个连接数(50 * 20 千 = 1 百万)。

然后我使用命令 sudo -i将 web 服务以 root 身份运行,这之后执行 ulimit -n 1024000命令,接着对 node examples/WebSocket.js(在 uWebSockets.js 文件夹中)也这么做。

真得就是这样的。客户端侧做了类似的配置,但是显然不需要设置多个 IP 地址。客户端电脑运行一个由 uSockets编写的单线程 C 客户端。这个测试的源代码都是开源的,同时客户端的代码是位于 uWebSockets/benchmarks 文件夹的『scale_test.c』。你可能需要为你自己的运行做一些小改动。

WebSocket 连接数量需要花几分钟才能达到 100 万个,如果我们想做的改进的话可以增加每批次的连接数和使用多个线程的客户端(诸如此类),但是这与我们对服务端感兴趣的点无关。服务端运行在单个线程上并且在连接阶段或之后 CPU 占用率都很低。

首先,让我们讨论一下 5k 个关闭的连接。uWebSockets.js 被配置为丢弃和杀死所有闲置已超过 60s 的 WebSocket 连接。『idleTimeout』就被用到了,这意味着我们需要在每 60s 就要与每 100 万个 WebSocket 连接主动发送和接收一条 WebSocket 消息。

你可以在这上面这张网络图中看到与 ping 消息相关的流量峰值。每秒最少有 16.7k 条 WebSocket 消息需要到达服务器 —— 都变少了之后我们开始关闭连接。

显然我们通过 Wifi 网络没有很好地满足这个标准。我们是丢失了一些连接,但在一个没有花哨配置的 WiFi 网络环境下仍存活 995k 个 WebSocket 连接却是很酷的事情!

服务端的 CPU 使用率保持在 0–2% 范围,用户控空间内存使用大约为 500MB 而整体系统范围的内存使用大约为 4.7GB。CPU 使用率或者内存使用一直都没有出现服务端激增走势,它始终处于完全稳定状态。

好吧!那么让我们拿出大杀器吧 —— Ethernet。我们将服务器和客户端连接到 1Gbit 消费级路由器并重新运行测试:

结果是服务运行状况稳定,而且没有连接丢失,WiFi 网络稳定性不足但是 Ethernet 却表现很好。为了保证每项都是稳定的,我让客户端和服务器持续运行了一个小时,这样没有一个连接丢失,然后有约 1.2 亿条 WebSocket 消息(16.7k * 60 * 60 * 2):

每项都是稳定良好运行。事实上,我在运行服务的笔记本上写着本文,并且被关闭的 socket 连接数量始终为 0,同时系统也是响应及时的。甚至我开启一个简单的游戏的情况下服务还能让连接继续。

此时我们已经实现了一个非常酷的概念验证场景。有一部分归因于稳定的 Ethernet 连接,但当然很大程度上也依赖服务端软件。任何其他的 Node.js 软件栈都无法实现这一壮举 —— 它们都不具备像这样足以在笔记本上维持这么多 WebSocket 连接的轻量级和高性能特点。你可以在系统变得无响应时停止 swap 分区交换,并且下面看到的这样来停止获取 ping 结果:

如果我们使用另一个服务软件栈可能运行不太好,这里『websockets/ws』 发生彻底崩溃并触发了重试

使用 uWebSockets.js,我们可以在这台笔记本上运行几十万个 WebSocket 连接,但是超过 100 万的常规连接则需要重新编译具备不同限制的 Linux 内核,这也是我们把它作为边界值的原因。

这里我们不打算去研究底层的嵌入式 C 开发,并且我认为这是明智的选择。只需启动一个新应用实例,一台新笔记本,通过这种方式继续扩展你的问题。

如果你对这个软件栈感兴趣,有 I/O 扩展性问题,或者想要避免陷入许多常见陷阱,一定要联系我们,我们可以通过公司对公司的形式来研讨问题。

感谢你的阅读!

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接即为本文在 GitHub 上的 MarkDown 链接。


相关 [node js 百万] 推荐:

node js 断点调试

- - Web前端 - ITeye博客
大部分基于 Node.js 的应用都是运行在浏览器中的,. 例如强大的调试工具 node-inspector. node-inspector 是一个完全基于 Node.js 的开源在线调试工具,提供了强大的调试功能和友好. 的用户界面,它的使用方法十分简便. 首先,使用 npm install -g node-inspector 命令安装 node-inspector,然后在终.

什么是Node?

- We_Get - 博客园新闻频道
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料.   译文全文:http://jayli.github.com/whatisnode/index.html.   作者:Brett McLaughlin ,原文:What is Node?.

Node入门

- - CSDN博客编程语言推荐文章
作者:  Manuel Kiessling. 翻译:  goddyzhao &  GrayZhang &  MondayChen. 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识. 本书绝不是一本“Hello World”的教程. 你正在阅读的已经是本书的最终版.

浅析Hadoop Secondary NameNode,CheckPoint Node,Backup Node

- - CSDN博客云计算推荐文章
Hadoop SecondaryNameNode并不是Hadoop 第二个NameNode,它不提供NameNode服务,而仅仅是NameNode的一个工具. 这个工具帮助NameNode管理Metadata数据. NameNode的HDFS文件信息(即Metadata)记录在内存中,client的文件写操作直接修改内存中的Metadata,同时也会记录到硬盘的Edits文件,这是一个Log文件.

[译]什么是Node?

- blacktulip - Taobao UED Team
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料. 译文全文:http://jayli.github.com/whatisnode/index.html. 作者:Brett McLaughlin ,原文:What is Node?.

用node作桌面开发

- InterMa - CNode社区
node的定位是,server-side javascript. 但程序员最爱做的事,就是把一个东西用在不该用的地方. 那么,可以把node用在桌面开发上吗. 把Javascript用在桌面开发上,早有先例,比如GTK+的gjs,还有Qt的QML(顺带一提,QML代表着桌面开发的另一个方向,a promising way),GNOME3中,也用javascript作为桌面插件的开发语言.

Vercel 部署 Node 服务

- - 掘金 前端
之前在写 面试常客:HTTP 缓存时,曾经就强缓存和协商缓存写过两个demo,但缓存要在服务端做,只能贴上代码,不能在网页上感受(虽然我贴了gif). 笔者的所有 demo 例子都放在 github page 上,其特点是不需要服务器即可部署静态资源,但它不具备部署服务端应用能力. 最近笔者在了解 CI/CD 方面的知识点,想起了 Vercel,就想着能否将服务端应用架在 vercel 上呢.

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

無痛安裝 NodeJS 和 Node Framework Express

- Hming - 小惡魔 - 電腦技術 - 工作筆記 - AppleBOY
直接到官網下載 Stable 的版本吧,目前是 node-v0.4.10.tar.gz,也可以先看看 API Document. 安裝 Ububtu 相關套件. 下面會使用最原始的編譯方式,所以必須安裝 g++ 套件,否則下 ./configure 的時候,會吐出來沒有安裝過的套件. 兩種方法:1.用 apt-get install nodejs 2.