Socket.io pm2 перезагружает дубликаты сокетов

Я запускаю node.js в кластерном режиме с socket.io и pm2 вот так (пример по умолчанию socket.io chat "hello world")

var
    probe = require('pmx').probe(),
    app = require('express')(),
    server = require('http').createServer(app),
    io = require('socket.io')(server),

    port = 3131 + parseInt(process.env.NODE_APP_INSTANCE),
    counter = probe.counter({
        name: 'User online'
    });



io.on('connection', function(socket) {
    counter.inc();
    socket.on('disconnect', function() {
        counter.dec();
    });

    socket.on('message', function() {
        socket.emit('message', port);
    });
});

server.listen(port, function() {});

и клиент html по умолчанию (все, кто посещает мою страницу, выполняют это)

var socket;
window.addEventListener("load", function() {
    socket = io.connect('http://localhost:3000/', {
        'reconnection': true,
        'reconnectionDelay': 500,
        'reconnectionAttempts': 3
    });

    socket.on('message', function(message) {
        console.log(message);
    });

    setInterval(function() {
        socket.emit('message', {});
    }, 2000);
});

это происходит с конфигурацией прикрепленных сеансов nginx по умолчанию (http://socket.io/docs/using-multiple-nodes/ найдено здесь, одно отличие, я пропустил последнюю часть Redis, используется только конфигурация nginx)

upstream io_nodes {
    ip_hash;
    server 127.0 .0 .1: 3131;
    server 127.0 .0 .1: 3132;
    server 127.0 .0 .1: 3133;
    server 127.0 .0 .1: 3134;
    server 127.0 .0 .1: 3135;
    server 127.0 .0 .1: 3136;
    server 127.0 .0 .1: 3137;
    server 127.0 .0 .1: 3138;
}

и конфигурацию pm2 вот так:

{
    "apps": [{
        "name": "server",
        "script": "server.js",
        "instances": 8,
        "exec_mode": "cluster",
        "max_memory_restart": "2G"
    }]
}

И у меня несколько проблем:

  1. Во-первых, количество онлайн-пользователей выше, когда подсчитывается весь мой проект онлайн-пользователей, например (реальный случай!), Если у меня 3800 пользователей онлайн, мои ключевые показатели (или простой io.eio.clientsCount) показывают 4000 или даже 5000 подключенных клиентов.

  2. Из первого следует, что если я использую перезагрузку pm2 или перезагрузку pm2, у меня есть случай, когда первый узел дублирует или даже умножает количество сокетов в несколько раз и получает 100% + загрузку процессора. Иногда подсчитываются все узлы, а не только первое умножение сокетов. Чтобы этого избежать, мне нужно убить pm2, подождать минуту, а когда начнется снова.

Ситуация после перезагрузки pm2 (реально в сети всего 3868 пользователей):

реально в сети всего 3868 пользователей


person MyMomSaysIamSpecial    schedule 11.11.2016    source источник
comment
Для вашей первой проблемы socket.io делает запрос к серверу более одного раза. Из-за этого Keymetrics может показывать больше, чем ожидалось. Я рекомендую поделиться с ними этой проблемой. Интересно и решение вашей второй проблемы.   -  person efkan    schedule 11.11.2016
comment
Возможное решение (идея) github.com/Unitech/pm2/issues/2508# issuecomment-259962370   -  person MyMomSaysIamSpecial    schedule 11.11.2016


Ответы (1)


если вы не против использовать только один процесс для обработки ws, вы можете сделать это:

let clusterId = process.env.NODE_APP_INSTANCE
if (clusterId > 0) return app
//otherwise, do atttch the ws server
person ZHAO Xudong    schedule 23.05.2017
comment
Спасибо, уже решил с аутентификацией через JWT, теперь все нормально :) - person MyMomSaysIamSpecial; 23.05.2017
comment
@MyMomSaysIamSpecial, если вы уже решили свою проблему, ответив на свой вопрос и отметив его как правильный ответ, принесет пользу всем - person Javohir Mirzo Fazliddinov; 01.04.2021