Node.js + Socket.io + Redis应用程序通过PM2具有大内存占用

时间:2015-10-12 15:53:28

标签: node.js sockets memory socket.io pm2

我是node.js和socket.io的新手,但我正在尝试构建一个监听Redis通知的简单服务(由PHP应用程序提供),并将它们广播给当前登录的任何用户,已连接到socket.io房间,例如'SITE_NAME:用户:USER_ID'。

我有它的工作,但Node应用程序的内存占用很快变得越来越大,从100mb到200 + mb非常快,大约有100个用户在线并积极浏览,我想知道我是否有一些设置这里错了。

PM2处理节点应用程序,nginx设置为反向代理。

服务器端:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
var redisClient = redis.createClient();
var allClients = [];

server.listen(8890);

io.sockets.on('connection', function (socket) {
    allClients.push(socket);

    socket.on('subscribe', function(data) {
        console.log('Joining room', data.room);
        socket.join(data.room);
        redisClient.subscribe(data.room);
    })

    socket.on('disconnect', function() {
        console.log('Disconnect');
        var i = allClients.indexOf(socket);
        delete allClients[i];
    });

});

// Watch for connection errors and log
redisClient.on('error', function (err) {
    console.log('Error event - ' + redisClient.host + ':' + redisClient.port + ' - ' + err);
});

redisClient.on('message', function(room, message) {
    console.log('New message: ' + message + '. In room: ' + room);
    io.sockets.in(room).emit('message', message);
});

客户方:

// connect to socket
socket = io.connect('http://localhost:8890');

// subscribe to user's room once connected
socket.on('connect', function(data){
    socket.emit('subscribe', { room: site_name + ':user:' + user_id });
});

// show messages from user's "room" via redis notifications
socket.on('message', function (response) {
    var json = new Hash(JSON.decode(response, true) || {});
    roar.alert(json.title, json.message, { link: json.link });
});

似乎这应该是一个非常精益的应用程序,不是吗?简单node.js应用程序的正常内存占用量是多少?

服务器以41mb启动,但即使没有任何人连接它,内存也会慢慢爬升,每分钟大约1mb。一旦我开始连接用户,它会迅速膨胀到200 + mb,直到我杀死它。

我不清楚如何最好地处理redisClient和套接字连接,因为用户连接&断开,我认为这可能是问题。但看到它在空闲时悄悄爬行是令人不安的。

  • PM2 v0.15.7
  • node v0.12.7
  • socket.io v1.3.7
  • express v4.13.3
  • nginx v1.6.2

任何帮助都非常感激。

1 个答案:

答案 0 :(得分:0)

我有一个类似的设置虽然它没有发布并且还没有进行过压力测试......但是这里有一个想法:

使用redis模块进行socketio(是否更好,然后redisClient会很有趣)。它使用不同的客户端进行pub'ing和sub'ing。 subClient使用detect_buffers。

var redisModule = require('socket.io-redis');
var redisAdapter= redisModule({
      host: redisClient.options.host
    , port: redisClient.options.port
    , pubClient: redisClient
    //, subClient: ... separate client that uses detect_buffers
});
io.adapter(redisAdapter);

然后subscribe / disconnect看起来像这样:

socket.on('subscribe', function(room) {
    socket.join(room);
});
socket.on('disconnect', function() {
    console.log('user disconnected');
});

我还多次阅读过,在某一点上,socketio不是最好的,而是使用sockjs。不知道是否仍然如此。

而且......因为我刚刚意识到已经超过2个月了。你找到了减少内存占用的东西吗?