Будет ли PM2 работать с сетевым API Node.js? - PullRequest
0 голосов
/ 30 апреля 2018

Фон

Мне нужно создать серверное приложение, которое прослушивает несколько соединений TCP. Это приложение должно быть легким, и TCP-соединения будут приходить с устройств GPS (не из браузеров, поэтому я не могу использовать WebSockets, например).

Исследование

Чтобы обеспечить правильное масштабирование до тысяч устройств, мне нужно в полной мере использовать все процессоры компьютеров. Согласно моему исследованию, я нашел 2 способа сделать это:

  1. Создайте сервер net и используйте собственный cluster API Node.js, предоставляющий
  2. Создайте приложение и используйте 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

Вопросы

  1. Возможно ли такое поведение с PM2? Если так Как (Как будет выглядеть код)?

1 Ответ

0 голосов
/ 28 мая 2018

Ответ

Итак, ответ здесь хитрый ...

Как работает кластер PM2

Итак, режим кластера PM2 фактически использует нативный API-интерфейс Node.js. Это означает, что использование нативных API-интерфейсов net и cluster от Node в значительной степени будет просто копировать работу, уже проделанную PM2, если только вы не захотите сделать это совершенно другим способом.

Будет ли кластер PM2 работать правильно с сокетами?

PM2 будет корректно масштабироваться с использованием функции cluster (которую я называю «разветвление» приложения с использованием PM2) при условии, что ваше приложение не имеет состояния .

Если это не так, PM2 не может ничего гарантировать.

http://pm2.keymetrics.io/docs/usage/cluster-mode/#statelessify-your-application

Заключение

Да, но ваше приложение должно быть без сохранения состояния.
Вам нужно сохранить ваши сокетные соединения и что-то в Redis или MongoDB или что-то еще.

...