通过PM2的Node.js + Socket.io + Redis应用程序占用大量内存 [英] Node.js + Socket.io + Redis app via PM2 with large memory footprint

查看:283
本文介绍了通过PM2的Node.js + Socket.io + Redis应用程序占用大量内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对node.js和socket.io都是新手,但是我试图构建一个简单的服务来侦听Redis通知(由PHP应用程序提供),并将其广播给当前已登录并已连接的所有用户到socket.io房间,例如'site_name:user:user_id'.

I'm new to both node.js and socket.io, but I'm trying to build a simple service that listens to Redis notifications (fed by PHP app), and broadcasts them to any users currently logged in, connected to a socket.io room e.g. 'site_name:user:user_id'.

我可以使用它,但是Node应用程序的内存占用迅速增加,从100mb迅速增长到200 + mb,大约有100位用户在线并正在积极浏览,我想知道是否设置了某些功能在这里错了.

I have it working, but the memory footprint of the Node app quickly gets larger and larger, going from 100mb to 200+mb pretty quickly with about 100 users online and actively browsing, and I'm wondering if I have something set up wrong here.

PM2正在处理节点应用程序,并且nginx被设置为反向代理.

PM2 is handling the node app, and nginx is set up as reverse proxy.

服务器端:

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应用程序的正常内存占用量是多少?

Seems like this should be a very lean app, no? What's a normal memory footprint for a simple node.js app?

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

The server starts up at 41mb, but even without anybody connecting to it, memory creeps up slowly, about 1mb a minute. Once I start connecting users, it bloats up quickly to 200+mb until I kill it.

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

I'm not clear on how best to handle the redisClient and socket connections as users connect & disconnect, and I thought that might be the issue. But seeing it creep up while idle is disconcerting.

  • PM2 v0.15.7
  • 节点v0.12.7
  • socket.io v1.3.7
  • 表达v4.13.3
  • nginx v1.6.2

非常感谢您的帮助.

推荐答案

尽管它尚未发布,也没有进行压力测试,但我也有类似的设置...但这是给您的一个想法:

I have a similar setup although it is not released and have done no stress testing yet... but here is an idea for you:

将redis模块用于socketio(是否有更好的方法,然后redisClient会很有趣).它使用不同的客户端进行发布和订阅.子客户端使用detect_buffers.

Use the redis module for socketio (whether it is any better then the redisClient would be interesting to know). It uses a different client for pub'ing and sub'ing. The subClient uses 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);

然后订阅/断开连接如下:

then subscribe/disconnect looks like this:

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

我也读过多次书,指出socketio并不是最好的选择,而是使用sockjs.不知道情况是否仍然如此.

I've also read multiple times that at one point socketio was not the best and to instead use sockjs. No idea if that is still the case.

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

And... since I just realized it's been more than 2 months. Did you find anything to reduce your memory footprint?

这篇关于通过PM2的Node.js + Socket.io + Redis应用程序占用大量内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆