Node.js + Socket.io + Redis 应用,通过 PM2 实现,内存占用大 [英] Node.js + Socket.io + Redis app via PM2 with large memory footprint

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

问题描述

我是 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
  • express 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:

为 socketio 使用 redis 模块(它是否比 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?

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

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