如何调试node.js导致100%的CPU使用率?

Tim*_*Tim 35 debugging node.js express

我有一个使用express和redis的节点应用程序.在我们的开发服务器上,经过一些使用后节点开始使用100%的cpu.应用程序仍然响应,但top报告节点使用100%.在重新启动节点之前,cpu不会丢弃.

我没有把它钉在导致它的任何特定路线或功能上.

诊断此问题的最佳方法是什么?

我用v8-profiler查看了node-inspector,它给了我同样的错误,这里报告了 https://github.com/dannycoates/v8-profiler/issues/10

lag*_*lex 21

您可以使用node-tick对您的应用进行分析.

  1. 安装node-tick方式sudo npm -g install tick
  2. 使用启用的配置文件运行您的应 node --prof ./app.js
  3. 使用CPU 100%使用一段时间后停止您的应用程序
  4. 您可以在app目录中看到v8.log,现在可以使用node-tick-processor读取它
  5. 运行node-tick-processor并解释结果
  6. 将v8.log加载到chrome://跟踪以分析为树.

node js cpu 100%

  • 我真的,真的希望这是一组步骤会回答我的问题,但是实现的v8.log当我运行节点蜱处理器没有响应后(CMD只是坐在那里),如果我打开相同的日志chrome://跟踪模块中的文件只报告一堆(空).在文本编辑器中,我看到了大量的操作(价值125MB),但我不知道如何解释这些信息. (2认同)

Tim*_*Tim 16

我通过编写脚本来记录每个请求然后重放它们来找到问题.

问题是因为我有一个没有返回的回调.

myAsncFunc(function(err, data) {

    if (err) { callback(err) }

    //node kept going after the error was returned to the user.
    // make sure you, return callback(err)

})
Run Code Online (Sandbox Code Playgroud)

这是我对任何感兴趣的人的replay.js代码.

var request = require('request');
var async = require('async');
var redis = require('redis');


var host = 'http://myhost.com';
var jobs = true;

var client = redis.createClient();

async.whilst(
    function () { return jobs; },
    function (callback) {
        client.lpop('history', function(err, url) {
            console.log(url);
            if (!url) {
                jobs = false;
                callback();
            }
            request.get({url:host+url}, function() {
                callback();
            });
        })
    },
    function (err) {
        console.log('done')
    }
);
Run Code Online (Sandbox Code Playgroud)

在你是快递应用程序.

app.get('/*', function(req, res, next) {
    var url = req.originalUrl;
    redis.rpush('history', url);   
    next();
});
Run Code Online (Sandbox Code Playgroud)

这很酷,因为播放的每个历史项目都会再次添加到队列中,因此它会不断循环,每次访问新页面时,它都会将其添加到队列中.

  • 蒂姆,你能解释为什么需要回归吗?由于函数中没有更多命令,节点是否只是超出范围? (7认同)
  • 这似乎不是真正的问题。如果有一个未使用的回调,它只占用内存,那么它就会被 GC 处理。 (2认同)

Dmi*_*hin 14

持续以 100% CPU 运行是无限循环的典型特征。这是单线程 Nodejs 中的一个真正问题,但不幸的是缺乏相关信息。尽管您声明您的服务器仍然响应并且无限循环不是您的情况,但您仍然可以找到调试实时 Nodejs 应用程序的有用提示。

\n

最终我找到了唯一有用的文章:\nHow to track the deadloop in nodejs:

\n

通过 SSH 连接到您的服务器。识别nodejs进程ID。\n现在,让\xe2\x80\x99s告诉进程监听调试请求。\n是的,我们\xe2\x80\x99使用一个名为kill的命令。不,我们\xe2\x80\x99不会终止该进程。我们\xe2\x80\x99正在向它发送不同的信号。

\n
kill -SIGUSR1 4702\n
Run Code Online (Sandbox Code Playgroud)\n

执行此操作后,该进程将打开调试器连接。事实上,它会在其控制台日志中打印一个特殊的 URL,您可以在 Chrome 中打开该 URL 来调试该过程!但是,也许您不想\xe2\x80\x99 只想在防火墙和容器配置中钻一个洞来建立连接。是的,我也一样。\n所以让\xe2\x80\x99s 在命令行进行调试:

\n
node inspect -p 4702\n
Run Code Online (Sandbox Code Playgroud)\n

您\xe2\x80\x99将看到以下提示:

\n
debug>\n
Run Code Online (Sandbox Code Playgroud)\n

然后输入:

\n
pause\n
Run Code Online (Sandbox Code Playgroud)\n

然后你回来:

\n
break in file:///somewhere/something.js:555\n>555         for (prop in inputObject) {\n510             if (hasOwnProp(inputObject, prop)) {\n511                 normalizedProp = normalizeUnits(prop);\n
Run Code Online (Sandbox Code Playgroud)\n

是的!我们有了第一个提示。该应用程序正在执行文件 Something.js 中的第 555 行。\n这可能足以立即看到该错误。但通常我们需要更多的信息。您可以输入 backtrace 来获取完整的堆栈跟踪:

\n
#0 someFunctionName file:///somewhere/somefile.js:444:22\n#1 someFunctionName file:///somewhere/somefile.js:555:33\n#2 someFunctionName file:///somewhere/somefile.js:666:44\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\xa6 等等。

\n


aki*_*nko 5

如果您将 UI 应用程序与 webpack 一起使用,请注意watchOptionswatch。对我来说,禁用轮询可以解决问题

watchOptions: {
            poll: false
        }
Run Code Online (Sandbox Code Playgroud)

或者您可以设置一个时间,轮询将被触发,例如poll: 3000(3秒一次) https://webpack.js.org/configuration/watch/#watchoptionsignored


小智 1

也许你在某个地方使用了一些计算,nextTick这会不断地浪费CPU。

如果您无法运行配置文件,那么很难找出哪个方法正在浪费CPU。另一件事是使用记录器中间件检查快速日志http://senchalabs.github.com/connect/middleware-logger.html