2016-11-11 90 views
0

我运行在集群模式下的Node.js与socket.io和PM2现在这个样子(默认socket.io聊天的 “Hello World” 的例子)Socket.io PM2重装复制插座

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个用户在线,我的keymetrics(或简单的io.eio.clientsCount)显示4000或甚至5000个连接的总客户端。从第一个,如果我使用pm2重新加载或pm2重新启动,我有情况下,当第一个节点重复或甚至乘以几次套接字计数,并获得100%+ cpu负载。有时候,所有的节点,不仅是首先乘以套接字数量。为了避免这种情况,我需要杀死pm2,等一下,然后再次开始。

PM2重装后状况(实际存在网上只有3868用户):

in real there is only 3868 users online

+0

对于你的第一个问题,'socket.io'向服务器发出一次以上的请求。因此,“Keymetrics”可能会显示更多的计数。我建议与他们分享这个问题。我想知道你的第二个问题的解决方案。 – efkan

+0

可能的解决方案(的想法)https://github.com/Unitech/pm2/issues/2508#issuecomment-259962370 – MyMomSaysIamSpecial

回答

0

,如果你不介意的话只用一个进程来处理WS, 你可以这样做:

let clusterId = process.env.NODE_APP_INSTANCE 
if (clusterId > 0) return app 
//otherwise, do atttch the ws server 
+0

谢谢,已通过JWT通过身份验证解决,现在一切都很好:) – MyMomSaysIamSpecial