48

我有一个使用 express 和 redis 的节点应用程序。在我们的开发服务器上,经过一段时间的使用 node 开始使用 100% cpu。应用程序仍然响应,但顶部报告节点使用 100%。在重新启动节点之前,cpu 不会下降。

我没有将其确定为导致它的任何特定路线或功能。

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

我用 v8-profiler 查看了节点检查器,它给了我这里报告的相同错误 https://github.com/dannycoates/v8-profiler/issues/10

4

9 回答 9

29

您可以使用node-tick分析您的应用程序。

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

节点 js cpu 100%

于 2015-02-05T16:25:59.877 回答
18

我通过编写脚本记录每个请求然后重放它们来发现问题。

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

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)

})

这是我的 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')
    }
);

而在你是快递应用程序。

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

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

于 2012-05-17T06:36:36.990 回答
6

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

最终我找到了唯一有用的文章:如何在 nodejs 中跟踪死循环:

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

kill -SIGUSR1 4702

执行此操作后,该过程将打开调试器连接。实际上,它会在其控制台日志中打印一个特殊的 URL,您可以在 Chrome 中打开该 URL 来调试进程!但是,也许您不想为了建立连接而在防火墙和容器配置中钻一个洞。是的,我也没有。因此,让我们在命令行中进行调试:

node inspect -p 4702

你会看到这个提示:

debug>

然后输入:

pause

你回来了:

break in file:///somewhere/something.js:555
>555         for (prop in inputObject) {
510             if (hasOwnProp(inputObject, prop)) {
511                 normalizedProp = normalizeUnits(prop);

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

#0 someFunctionName file:///somewhere/somefile.js:444:22
#1 someFunctionName file:///somewhere/somefile.js:555:33
#2 someFunctionName file:///somewhere/somefile.js:666:44

… 等等。

于 2020-09-22T15:48:57.773 回答
5

如果您使用 webpack 的 UI 应用程序,请注意watchOptionswatch。对我来说,禁用民意调查可以解决问题

watchOptions: {
            poll: false
        }

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

于 2020-02-13T12:23:20.380 回答
4

在我关闭主管模式之前,我也经历了 100% 的 CPU 使用率(当文件更改时导致节点重新启动)。

这可能无法回答这个问题,但如果像我这样的新手担心 CPU 使用率,可能就是这种情况。

于 2015-07-25T21:29:35.223 回答
2

如果您nodemon用来监视文件,请考虑使用文件较少的文件夹的路径。例如,让nodemon使用 bower 或 npm 安装的监视库文件夹会导致 CPU 使用率很高,因为其中包含数千个文件。

这是我的示例nodemon.json文件:

{
    "watch": ["views","routes"],
    "ext": "html, js"
}

奇迹般有效。

于 2019-02-16T07:57:41.460 回答
1

也许你在某处有一些计算nextTick正在不断地浪费 CPU。

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

于 2012-04-16T13:21:00.660 回答
1

另一种选择是我们可以使用火焰图并查看函数调用导致 cpu 高。命令可以找到如下

$> git clone https://github.com/brendangregg/FlameGraph.git

$> perf record -F 99 -p 1812 /*process id*/ -g --call-graph dwarf

$> perf script > out.perf

$> FlameGraph/stackcollapse-perf.pl out.perf > out.folded
$> FlameGraph/flamegraph.pl out.folded > out.svg
于 2020-06-23T11:13:17.857 回答
0

这可能是因为您直接拥有大量文件。例如 node_modules 文件夹。您需要使用 -i 参数来忽略该文件夹。所以它应该是这样的: supervisor -i ./node_modules app

于 2018-03-28T15:16:48.033 回答