如何修复 ws 和 socket.io 内存泄漏?

如何修复 ws 和 socket.io 内存泄漏?

我读到过,node.js websocket 模块 ws 和 socket.io 都存在内存泄漏。这个问题已经存在好几年了,我想知道该如何修复它。

下面提到了其中的一些:

鉴于现在是 2021 年,将 perMessageDeflate 键设置为 false 并预加载 jemalloc 仍然是最好的解决方案吗?

答案1

我对这个问题的初步理解如下(不要引用我的话):

  • ws node.js 模块(即 websockets 模块)和 socket.io node.js 模块都使用另一个名为 zlib 的模块。此模块负责在通过 websocket 发送消息时对其进行压缩。
  • zlib 模块过去曾出现过与内存碎片有关的问题,它模仿了内存泄漏(即,它实际上不是内存泄漏而是内存碎片)。
  • 服务器上默认禁用消息压缩,但客户端(例如浏览器)默认启用。如果我们禁用它,则不使用 zlib 模块,这将消除内存碎片问题。
  • 为了在客户端(例如浏览器)上禁用压缩,我们perMessageDeflate在服务器代码中为键赋予值false。即:

const wss = new WebSocket.Server({ server:httpsServer, perMessageDeflate: false });

显然,对于那些想要压缩消息的人来说,这不是一个解决方案。但值得一提的是:

  • zlib 的内存碎片问题显然已得到部分修复https://github.com/websockets/ws/pull/1204但这似乎仍然是一个问题;
  • 压缩小消息(例如小段文本)的好处一直存在争议。有些人甚至表示压缩小消息会使速度变慢。如果您要处理较大的数据(例如图像或视频),您可以在通过 websocket 发送之前自行压缩(即不使用 ws/socket.io/zlib)以取得成功。

此外,有人指出,设置 perMessageDeflate: false 只能减少问题,但不能完全解决问题。我想请您注意这个讨论,其中说打开和关闭 websocket 时的一些残留和恒定(即不增加)内存使用是正常的(顺便说一句,我不一定说这是正确的):https://github.com/websockets/ws/issues/804#issuecomment-302612661

至于预加载 Jemalloc,这似乎并不能解决问题。但如果上述代码不起作用,那么肯定值得研究(或尝试)。

那么这是preMessageDeflate: false目前最好的解决方案吗?根据我的理解,我认为是的。

如果有人对此有更正或更多信息,请添加。

相关内容