跳到主要內容
版本: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)。

另請參閱