PM2 可以与 Node.js net API 一起使用吗?
Will PM2 work with Node.js net API?
背景
我需要制作一个监听多个 TCP 连接的服务器应用程序。这个应用程序必须是轻量级的,TCP 连接将来自 GPS 设备(而不是来自浏览器,所以我不能使用 WebSockets 例如)。
研究
为了确保它能正确扩展到数千台设备,我需要充分利用所有机器的 CPU。根据我的研究,我发现了两种方法:
据我了解,这些选项是相互排斥的。如果我选择选项1,则无法使用PM2,反之亦然。
问题
我的团队到处都使用 PM2,因此为了保持一致性,我也想使用 PM2。这里的问题是 PM2 与 Node.js 套接字应用程序有问题。例如,我知道要使用 socket.io
我们需要安装额外的模块( sticky-session
)但是因为我使用的是原生 API 没有信息
关于我需要做什么调整。
使用本机 net
API 我不知道 PM2 是否会在 CPU 之间平均分配连接,也不知道数据是否会在适当的时候发送给正确的工作人员来了。
代码
为了演示我的 objective 我使用 cluster
原生 Node.js API:
制作了一个小应用程序
const cluster = require("cluster");
const net = require("net");
const numCPUs = require("os").cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on("exit", (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
const server = net.createServer( connection => {
console.log(`Client connected to ${process.pid}`);
connection.on( "end", () => console.log( `Client disconnected from ${process.pid}` ) );
connection.on( "data", data =>console.log(`${process.pid} received ${data.toString("ascii")}`) );
connection.on( "close", () => console.log(`Client closed connection with ${process.pid}`) );
} );
server.listen( 8124, () => console.log(`Worker ${process.pid} Bound`) );
console.log(`Worker ${process.pid} started`);
}
根据我对文档的了解,此服务器通过所有 CPU 平衡负载并重定向连接。
您可以使用 telnet 尝试此示例:telnet localhost 8124
问题
- PM2 可以实现这种行为吗?如果是这样如何(代码会是什么样子)?
回答
所以,这里的答案很棘手...
PM2 集群的工作原理
所以,PM2集群模式实际上使用了Node.js原生的API。这意味着使用来自 Node 的 net
和 cluster
原生 APIs 几乎只是复制 PM2 已经完成的工作,除非您想以完全不同的方式进行。
PM2 集群能否与套接字一起正常工作?
如果您的应用程序是 stateless,PM2 将使用 cluster
功能正确缩放(我将其称为 "fork" 使用 PM2 的应用程序)。
如果不是,PM2不能保证什么。
http://pm2.keymetrics.io/docs/usage/cluster-mode/#statelessify-your-application
结论
是的,但您的应用需要是无状态的。
您需要保存套接字连接以及 Redis 或 MongoDB 或其他内容。
背景
我需要制作一个监听多个 TCP 连接的服务器应用程序。这个应用程序必须是轻量级的,TCP 连接将来自 GPS 设备(而不是来自浏览器,所以我不能使用 WebSockets 例如)。
研究
为了确保它能正确扩展到数千台设备,我需要充分利用所有机器的 CPU。根据我的研究,我发现了两种方法:
据我了解,这些选项是相互排斥的。如果我选择选项1,则无法使用PM2,反之亦然。
问题
我的团队到处都使用 PM2,因此为了保持一致性,我也想使用 PM2。这里的问题是 PM2 与 Node.js 套接字应用程序有问题。例如,我知道要使用 socket.io
我们需要安装额外的模块( sticky-session
)但是因为我使用的是原生 API 没有信息
关于我需要做什么调整。
使用本机 net
API 我不知道 PM2 是否会在 CPU 之间平均分配连接,也不知道数据是否会在适当的时候发送给正确的工作人员来了。
代码
为了演示我的 objective 我使用 cluster
原生 Node.js API:
const cluster = require("cluster");
const net = require("net");
const numCPUs = require("os").cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on("exit", (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
const server = net.createServer( connection => {
console.log(`Client connected to ${process.pid}`);
connection.on( "end", () => console.log( `Client disconnected from ${process.pid}` ) );
connection.on( "data", data =>console.log(`${process.pid} received ${data.toString("ascii")}`) );
connection.on( "close", () => console.log(`Client closed connection with ${process.pid}`) );
} );
server.listen( 8124, () => console.log(`Worker ${process.pid} Bound`) );
console.log(`Worker ${process.pid} started`);
}
根据我对文档的了解,此服务器通过所有 CPU 平衡负载并重定向连接。
您可以使用 telnet 尝试此示例:telnet localhost 8124
问题
- PM2 可以实现这种行为吗?如果是这样如何(代码会是什么样子)?
回答
所以,这里的答案很棘手...
PM2 集群的工作原理
所以,PM2集群模式实际上使用了Node.js原生的API。这意味着使用来自 Node 的 net
和 cluster
原生 APIs 几乎只是复制 PM2 已经完成的工作,除非您想以完全不同的方式进行。
PM2 集群能否与套接字一起正常工作?
如果您的应用程序是 stateless,PM2 将使用 cluster
功能正确缩放(我将其称为 "fork" 使用 PM2 的应用程序)。
如果不是,PM2不能保证什么。
http://pm2.keymetrics.io/docs/usage/cluster-mode/#statelessify-your-application
结论
是的,但您的应用需要是无状态的。
您需要保存套接字连接以及 Redis 或 MongoDB 或其他内容。