node.js 应用程序突然以 100% 加载 CPU 并挂起

Posted

技术标签:

【中文标题】node.js 应用程序突然以 100% 加载 CPU 并挂起【英文标题】:node.js application suddenly loads CPU at 100% and hangs 【发布时间】:2013-05-22 21:12:18 【问题描述】:

我在 linux 虚拟机上运行的 node.js 上有一个简单的应用程序。它监听 tcp 消息并使用 socket.io 库将它们发送到客户端。在一段时间的低 CPU 使用率之后,它突然开始越来越高地加载 CPU,直到应用程序挂起。脚本很简单,我不明白它有什么问题。

var net = require('net');
var io = require('socket.io').listen(socketPort);

net.createServer(function (socket) 
    socket.setEncoding("utf8");
    socket.on('data', function (dataStr) 
        console.log("TCP dataStr " + dataStr);
        var data = JSON.parse(dataStr);
        io.sockets.in(data.room).emit('publish', data);
    );
).listen(tcpPort);

io.sockets.on('connection', function (socket) 

    socket.on('subscribe', function (room) 
        console.log('subscribe room ' + room);
        if (Array.isArray(room)) 
            var i;
            for (i = 0; i < room.length; i++) 
                console.log('subscribe join room ' + room[i]);
                socket.join(room[i]);
            
         else if (typeof room === 'string') 
            console.log('subscribe join room ' + room);
            socket.join(room);
        
    );

    socket.on('unsubscribe', function (room) 
        console.log('unsubscribe room ' + room);

        if (Array.isArray(room)) 
            var i;
            for (i = 0; i < room.length; i++) 
                console.log('unsubscribe leave room ' + room[i]);
                socket.leave(room[i]);
            
         else if (typeof room === 'string') 
            console.log('unsubscribe leave room ' + room);
            socket.leave(room);
        

    );

);

我还尝试使用集群模块运行多个与客户端通信的工作人员。一段时间后,每个工人都会以 100% 的速度挂起自己的 CPU 内核,时差约为一分钟。

UPD:客户端代码(在浏览器中运行):

    socketObj = new function() 
        var that = this;
        that.socket;

        that.init = function(nodeServerUrl, rooms, onPublishFunc) 
            that.socket = io.connect(nodeServerUrl);
            that.socket.emit('subscribe', rooms);

            that.socket.on('publish', function(data) 
                        onPublishFunc(data);
            );
        ;
        that.subscribe = function(room) 
            that.socket.emit('subscribe', room);
        ;
        that.unsubscribe = function(room) 
            that.socket.emit('unsubscribe', room);
        ;
    

    ...

    try 
        socketObj.init('application url', ["room1", "room2"], nodeJsCallback);
     catch(err) 
    

    ...

    nodeJsCallback = function(jsonData) 
        //Only updates data on UI, no subscribing, unsubscribing, emitting etc.
        ...
    

UPD2:我尝试在生产机器和本地 Windows 机器上通过综合测试重现问题。我做了一些压力测试:

    多个客户端套接字连接 多个静态数据下载(浏览器的socket.io脚本) tcp 更新频率增加。

经过几个小时的测试,我无法重现。但是,当它与真实用户一起在生产环境中运行时,它会早晚挂断。

我开始认为这是环境问题或特定消息问题。我接下来要尝试的可能是:

    将 Node.js 更新到当前版本 尝试记录所有数据传输并稍后重播,希望挂起会重现

【问题讨论】:

你在为 socket.io 存储使用 RedisStore 吗? 这是脚本的第一个版本。在这种情况下,我没有使用 Redis 作为存储并且有 1 个进程。第二个版本是使用带有 Redis 的 socket.io,1 个进程监听 tcp 消息并转发到 2 个与客户端浏览器通信的进程。第二个版本也挂了。 你的 Node/socket.io 版本是最新的吗? 控制台上显示了什么? 100% CPU 通常是循环的标志。 @robertklep 安装时它是最新的。据我所知,Node.js 是 v0.10.5,socket.io 是 0.9.12。明天我会尝试最新版本的 Nodejs。 【参考方案1】:

将 Nodejs 从版本 v0.10.4(稳定)更改为 v0.11.2(不稳定)。到目前为止一切正常,消耗 1-2% 的 CPU。现在我们正在 v0.10.8(Stable) 上进行测试。

UPD 在 v0.10.8 上应用也很稳定。

尽管问题在 v0.10.4(Stable) 上消失了,但仍然非常奇怪和令人沮丧。

【讨论】:

以上是关于node.js 应用程序突然以 100% 加载 CPU 并挂起的主要内容,如果未能解决你的问题,请参考以下文章

如何找出 Node.js 服务器 CPU 100% 的原因?

如何让 TypeScript 以生成工作 Node.JS 代码的方式加载 PDF.js NPM 模块和 @types 绑定?

为 node.js 重新加载。有可能吗? [复制]

安装node.js,及vue-cli脚手架和webpack加载打包工具

Node.js 应用程序无法在 heroku 上启动

产生 ENOENT node.js 错误