跳至主要内容
版本: 4.x

性能调优

以下是一些提高 Socket.IO 服务器性能的技巧

您可能也对 扩展到多个节点 感兴趣。

在 Socket.IO 级别

由于在大多数情况下,Socket.IO 连接将使用 WebSocket 建立,因此 Socket.IO 服务器的性能将与底层 WebSocket 服务器的性能密切相关(ws,默认情况下)。

安装 ws 本机插件

ws 带有两个可选的二进制插件,可以提高某些操作的效率。预构建的二进制文件可用于最流行的平台,因此您不一定需要在机器上安装 C++ 编译器。

  • bufferutil: 允许有效地执行操作,例如对 WebSocket 帧的数据有效负载进行掩码和取消掩码。
  • utf-8-validate: 允许有效地检查消息是否包含规范要求的有效 UTF-8。

要安装这些包

$ npm install --save-optional bufferutil utf-8-validate

请注意,这些包是可选的,如果它们不可用,WebSocket 服务器将回退到 Javascript 实现。更多信息可以找到 这里.

使用其他 WebSocket 服务器实现

例如,您可以使用 eiows 包,它是(现在已弃用)uws 包的派生版本

$ npm install eiows

然后使用 wsEngine 选项

const { createServer } = require("http");
const { Server } = require("socket.io");

const httpServer = createServer();
const io = new Server(httpServer, {
wsEngine: require("eiows").Server
});

使用自定义解析器

如果您通过 Socket.IO 连接发送二进制数据,使用基于 msgpack自定义解析器 可能很有趣,因为默认情况下每个缓冲区将在其自己的 WebSocket 帧中发送。

用法

服务器

const { createServer } = require("http");
const { Server } = require("socket.io");
const parser = require("socket.io-msgpack-parser");

const httpServer = createServer();
const io = new Server(httpServer, {
parser
});

客户端

const { io } = require("socket.io-client");
const parser = require("socket.io-msgpack-parser");

const socket = io("https://example.com", {
parser
});

丢弃初始 HTTP 请求

默认情况下,每个会话的第一个 HTTP 请求的引用将保存在内存中。例如,在使用 express-session 时需要此引用(请参阅 这里),但可以丢弃它以节省内存

io.engine.on("connection", (rawSocket) => {
rawSocket.request = null;
});

之前

Memory usage before

之后

Memory usage with request discarded

在操作系统级别

有很多关于如何调整操作系统以接受大量连接的优秀文章。请参阅 这篇文章这篇文章 例如。

在对 Socket.IO 服务器进行 负载测试 时,您可能会遇到以下两个限制

  • 最大打开文件数

如果您无法超过 1000 个并发连接(新客户端无法连接),那么您很可能已达到最大打开文件数

$ ulimit -n
1024

要增加此数字,请创建一个新文件 /etc/security/limits.d/custom.conf,其中包含以下内容(需要 root 权限)

* soft nofile 1048576
* hard nofile 1048576

然后重新加载您的会话。您的新限制现在应该已更新

$ ulimit -n
1048576
  • 最大可用本地端口数

如果您无法超过 28000 个并发连接,那么您很可能已达到最大可用本地端口数

$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999

要增加此数字,请创建一个新文件 /etc/sysctl.d/net.ipv4.ip_local_port_range.conf,其中包含以下内容(同样需要 root 权限)

net.ipv4.ip_local_port_range = 10000 65535

注意:我们使用 10000 作为下限,因此它不包括机器上服务使用的端口(例如,PostgreSQL 服务器的 5432),但您可以完全使用更低的值(低至 1024)。

重新启动机器后,您现在将能够愉快地达到 55k 个并发连接(每个传入 IP)。

另请参阅