Skip to main content
Version: 4.x

与 PM2 一起使用

PM2 是 Node.js 应用的生产进程管理器,具有内置负载均衡器。它允许你使应用永远保持活动状态,无需停机即可重新加载它们,并简化常见的系统管理任务。

¥PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

你可以在这里找到它的文档:https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/

¥You can find its documentation here: https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/

要使用 PM2 扩展 Socket.IO 服务器,有以下三种解决方案:

¥To scale a Socket.IO server with PM2, there are three solutions:

  • 在客户端禁用 HTTP 长轮询

    ¥disable HTTP long-polling on the client-side

const socket = io({
transports: ["websocket"]
});

但在这种情况下,如果无法建立 WebSocket 连接,则不会回退到 HTTP 长轮询。

¥Though in that case, there will be no fallback to HTTP long-polling if the WebSocket connection cannot be established.

  • 为每个工作进程使用不同的端口,并在它们前面使用像 nginx 这样的负载均衡器

    ¥use a distinct port for each worker, and a load-balancer like nginx in front of them

  • 使用 @socket.io/pm2

    ¥use @socket.io/pm2

安装

¥Installation

npm install -g @socket.io/pm2

如果 pm2 已安装,则必须先将其删除:

¥If pm2 is already installed, you will have to remove it first:

npm remove -g pm2

@socket.io/pm2 可用作 pm2 的直接替代品,并支持 pm2 类实用程序的所有命令。

¥@socket.io/pm2 can be used as a drop-in replacement for pm2, and supports all the commands of the class pm2 utility.

唯一的区别来自 这次提交

¥The only difference comes from this commit.

用法

¥Usage

worker.js

const { createServer } = require("http");
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/cluster-adapter");
const { setupWorker } = require("@socket.io/sticky");

const httpServer = createServer();
const io = new Server(httpServer);

io.adapter(createAdapter());

setupWorker(io);

io.on("connection", (socket) => {
console.log(`connect ${socket.id}`);
});

ecosystem.config.js

module.exports = {
apps : [{
script : "worker.js",
instances : "max",
exec_mode : "cluster"
}]
}

然后运行 pm2 start ecosystem.config.js(或 pm2 start worker.js -i 0)。就是这样!你现在可以通过端口 8080 访问 Socket.IO 集群。

¥And then run pm2 start ecosystem.config.js (or pm2 start worker.js -i 0). That's it! You can now reach the Socket.IO cluster on port 8080.

工作原理

¥How it works

扩展到多个节点 时,有两件事要做:

¥When scaling to multiple nodes, there are two things to do:

  • 启用粘性会话,以便 Socket.IO 会话的 HTTP 请求路由到同一个工作线程

    ¥enable sticky sessions, so that the HTTP requests of a Socket.IO session are routed to the same worker

  • 使用自定义适配器,以便数据包广播到所有客户端,即使它们连接到另一个工作线程

    ¥use a custom adapter, so that the packets are broadcast to all clients, even if they are connected to another worker

为了实现这一目标,@socket.io/pm2 包含两个附加软件包:

¥In order to achieve this, @socket.io/pm2 includes two additional packages:

pm2 的唯一区别来自 这次提交

¥The only difference with pm2 comes from this commit:

  • God 进程现在创建自己的 HTTP 服务器并将 HTTP 请求路由到正确的工作进程

    ¥the God process now creates its own HTTP server and routes the HTTP requests to the right worker

  • God 进程还在 worker 之间中继数据包,以便 io.emit() 正确到达所有客户端

    ¥the God process also relays the packets between the workers, so that io.emit() correctly reaches all clients

请注意,如果你有多个主机,每个主机都运行 PM2 集群,则必须使用另一个适配器,例如 Redis 适配器

¥Please note that if you have several hosts each running a PM2 cluster, you will have to use another adapter, like the Redis adapter.

复刻的源代码可以在 此处 找到。我们将尽力密切关注 pm2 软件包的发布。

¥The source code of the fork can be found here. We will try to closely follow the releases of the pm2 package.