【问题标题】:How many events can socket.io handle?socket.io 可以处理多少个事件?
【发布时间】:2019-04-18 18:53:20
【问题描述】:

我正在为我的个人项目尝试 Socket.io(服务器和客户端)。因为这是我第一次尝试使用 node.js,甚至是 javascript 和 mongodb,我对我的服务器的性能有点困惑。

我创建了一个包含许多事件和许多房间的复杂实时系统。服务器的事件非常有限,但客户端的事件太多。这些事件分布在房间下。

例如——

  • R1房间>> 事件 R1E1, 事件 R1E2, 事件 R1E3.... 事件 R1EN

  • R2房间>> 事件 R2E1, 事件 R2E2, 事件 R2E3.... 事件 R2EN

所有数据都存储在mongodb中。工作真棒。

但是,当注册了 10-15 个事件的少数客户端 (5-8) 开始发送数据时,就会出现问题。服务器最初工作正常,但几分钟后它停止响应。即使服务器没有响应,客户端也会保持连接。请求堆积如山。有时服务器会收到最后一个会话请求。

这一切都从最终设备开始注册事件开始。 所以我想知道 socket.io 可以处理多少事件?

P.S.我认为“事件”是-

io.on('event', function(msg){
    console.log( msg);
});

编辑 2

当我研究 node.js 时,节点基本上是一个在单个线程上运行的进程,如果它需要处理其他事情,它会启动另一个节点(异步线程),让新线程独自完成它的进程并返回到主线程运行。如果我们想处理一些进程序列,我们使用“async/await”。

在我的情况下,当客户端第一次连接时,我只在一个地方使用异步。这里我查询了 3 个不同的 mongodb 集合,并返回一个事件的数据。

我的服务器当前在 MacBook Pro(16 GB RAM,i7 第 6 代四核)上运行。它应该处理至少 4-6 个并发线程。

我创建了一个负载测试,100000 个不同的事件分布在 1000 个房间下,每秒有 5 个请求查询数据库。它工作正常。几乎 40% 的 RAM 和 250% 的 CPU 是最大负载。

我与 db 的连接是持久的,这意味着我会在服务器启动后立即连接到 db 并保持该连接引用处于活动状态。

那么问题出在哪里?

【问题讨论】:

  • 我没有给你一个明确的答案,但我认为瓶颈可能在你的事件处理的某个地方,而不是 Socket.io 本身。话虽如此,如果您希望您的应用程序增长,我将开始研究如何使用 socket.io (socket.io/docs/using-multiple-nodes/…) 设置多个节点。通过将事件处理程序放入单独的流程循环中,仅此一项可能会有所帮助。
  • 在我的情况下,服务器和客户端将有许多“redis”。我已经测试了性能基准测试,它很好,当前场景只占该基准测试的一小部分。所以从技术上讲它应该可以工作。

标签: javascript node.js mongodb socket.io iot


【解决方案1】:

所以我只想知道 socket.io 可以处理多少事件?

首先,不清楚您是在谈论 socket.io 服务器可以拥有多少个事件处理程序,还是在询问 socket.io 有多少实时事件(如事件/秒)服务器可以处理。

在第一项上,socket.io 服务器可以处理多少个事件处理程序没有编码限制。套接字派生自 EventEmitter,它使用 EventEmitter 的侦听器功能来允许某人侦听事件。该基础设施没有编码限制,甚至没有真正的实际限制,因为它是一个非常轻量级的系统。

一般而言,需要数千个单独编码的事件侦听器的系统可能可以通过其他方式更有效地设计,但我们必须了解您正在做什么的更多细节才能知道如何更具体地提出建议。


至于 socket.io 服务器每秒可以处理多少条消息,这完全取决于服务器在处理每条消息时所做的工作、服务器有多少带宽、服务器处理每条消息的速度等等开。


除非您一次用数以万计的消息淹没您的服务器或对每条消息进行大量处理,否则我猜您的服务器问题可能与您的服务器代码的其他部分有关(可能与您正在做的事情有关)消息何时到达以及您如何处理它们)。

我还想知道您是否创建了某种循环消息循环,其中 clientA 将 msgA 发送到服务器。服务器接收到该消息,对其进行一些处理并将 msgB 发送到 clientA。 clientA 接收到该消息,对其进行一些处理,并且该处理的一些副作用导致它再次向服务器发出 msgA,您最终会得到一个永无止境的消息循环。

此外,socket.io 中的房间没有“有事件”或“接收事件”,因此您的部分描述没有真正意义。您可以将事件发送到房间内的所有套接字。但是,这实际上只会导致服务器遍历给定房间的所有成员,并分别向每个成员发送消息。


根据您的编辑,如果“事件”是这样的:

io.on('event', function(msg){
    console.log( msg);
});

然后,您的服务器每秒可以处理的事件数量取决于各种系统配置变量(带宽、CPU、数据库性能等)以及您为处理每个传入事件所做的处理量。以下是要做的事情的清单:

  1. 绝对确保在服务器启动时以外的任何地方都没有同步 I/O,因为这会立即破坏您同时处理大量“进行中”事件的能力。
  2. 使处理每个事件的代码尽可能高效。如果您在每个事件上都咨询数据库,那可能会将您的数据库设置为瓶颈。
  3. 设计一些测试来找出处理中的第一个瓶颈。
  4. 改善第一个瓶颈的性能特征。
  5. 冲洗、泡沫重复,直到您移除/改善了您遇到瓶颈的前 N ​​个地方。

请记住,单个 node.js 实例只有一个运行 Javascript 的线程。因此,如果您希望能够处理 100 条消息/秒,则可以使用不超过 10 毫秒的 CPU 来处理每条消息(1000 毫秒/秒除以 100 条消息/秒 = 10 毫秒/消息)。如果 CPU 是您的实际瓶颈,您可以通过实施集群或启动多个进程来处理工作队列来扇出多个 CPU,但您必须首先通过测试确定这一点。

【讨论】:

  • 我不能把所有代码都放在这里,但我可以解释它是如何工作的。考虑一个仅在一个频道(或在房间内)通话的端到端加密系统。单独的数据库,服务器,客户端工作正常。服务器能够处理分布在 1000 个房间中的 100000 个事件,每秒有 5 个请求查询数据库。它占用了大约 40% 的 RAM 和 250% 的 CPU。
  • @HarvantS.Choudhary - 我不确定你是否看过我的答案的修改。如果您真的在询问您的服务器可以处理多少消息/秒,这完全取决于此处未披露的内容,并且最终只能通过为您的数据中心中的服务器设计适当的测试来回答,因为它取决于大量的环境因素(服务器配置、带宽、活动客户端的数量、每条消息的处理等等)。此外,如果您的服务器中有任何同步 I/O 代码,这也可能会破坏可伸缩性。
  • @HarvantS.Choudhary - 在我的答案末尾添加了更多内容。
  • 是的,它有帮助。我将更新我的负载测试代码将尝试这些方法。
猜你喜欢
  • 2020-08-18
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
相关资源
最近更新 更多