Фон
Мне нужно создать серверное приложение, которое прослушивает несколько соединений TCP. Это приложение должно быть легким, и TCP-соединения будут приходить с устройств GPS (не из браузеров, поэтому я не могу использовать WebSockets, например).
Исследование
Чтобы обеспечить правильное масштабирование до тысяч устройств, мне нужно в полной мере использовать все процессоры компьютеров. Согласно моему исследованию, я нашел 2 способа сделать это:
- Создайте сервер
net
и используйте собственный cluster
API Node.js, предоставляющий
- Создайте приложение и используйте PM2 для «раскрутки» его на всех процессорах
Насколько я понимаю, эти опции являются взаимоисключающими. Если я выберу вариант 1, я не смогу использовать PM2 и наоборот.
Задача
Моя команда везде использует PM2, поэтому для согласованности я бы также хотел использовать PM2. Проблема здесь в том, что PM2 имеет проблемы с приложениями сокетов Node.js. Я знаю, например, что для использования socket.io
нам нужно установить дополнительные модули (sticky-session
), но, поскольку я использую нативный API, никакой информации
на каких адаптациях мне нужно что бы то ни было делать.
Использование нативного net
API. Я понятия не имею, будет ли PM2 равномерно распределять соединения между процессорами, и я не могу найти никакой информации, если данные придут к нужному работнику, когда придет время.
код
Чтобы продемонстрировать свою цель, я создал небольшое приложение с использованием cluster
нативного API Node.js:
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`);
}
В соответствии с тем, что я понимаю из документации, этот сервер балансирует нагрузку через все процессоры и перенаправляет соединения.
Вы можете попробовать этот пример, используя telnet: telnet localhost 8124
Вопросы
- Возможно ли такое поведение с PM2? Если так Как (Как будет выглядеть код)?