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

Debugging 如何调试node.js导致100%的cpu使用率?,debugging,node.js,express,Debugging,Node.js,Express,我有一个使用express和redis的节点应用程序。在我们的开发服务器上,经过一点使用之后,node开始使用100%的cpu。应用程序仍有响应,但top使用100%报告节点。在重新启动节点之前,cpu不会下降 我并没有把它和导致它的任何特定路线或功能联系起来 诊断此问题的最佳方法是什么 我用v8探查器查看了节点检查器,它给出了与此处报告的相同的错误 也许你在某个地方使用了nextTick进行了一些计算,这会不断地破坏CPU 若你们不能运行profile,那个么很难找出哪种方法会破坏cpu。还有

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

我并没有把它和导致它的任何特定路线或功能联系起来

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

我用v8探查器查看了节点检查器,它给出了与此处报告的相同的错误
也许你在某个地方使用了
nextTick
进行了一些计算,这会不断地破坏CPU


若你们不能运行profile,那个么很难找出哪种方法会破坏cpu。还有一件事是使用logger中间件检查express log

我通过编写脚本来记录每个请求,然后重播它们,从而发现了问题

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

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')
    }
);
在你的express应用程序中

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

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

您可以使用配置文件配置您的应用程序

  • 安装
    node tick
    by
    sudo npm-g安装tick
  • 使用启用的概要文件
    节点运行应用程序--prof./app.js
  • CPU使用率达到100%一段时间后,停止应用程序
  • 您可以在应用程序目录中看到v8.log,现在您可以使用node tick processor读取它
  • 运行
    节点勾选处理器
    并解释结果
  • 将v8.log加载到chrome://tracing 像树一样分析

  • 我也经历了100%的CPU使用率,直到我关闭了监控模式(导致节点在文件更改时重新启动)


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

    这可能是因为您直接使用了大量的文件。e、 g.节点模块文件夹。 您需要使用-i参数来忽略该文件夹。所以它应该是这样的:
    <代码>监控器- /NoDyMead应用程序 >

    在使用<代码> NoDimon < /代码>监视文件时,请考虑使用较少文件的文件夹的路径。e、 g.让
    nodemon
    监视安装了bower或npm的库文件夹会导致CPU使用率高,因为其中包含数千个文件

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

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

    工作起来很有魅力。

    如果您将UI应用程序与webpack一起使用,请注意
    监视选项
    监视
    。 对我来说,这可以解决问题

    watchOptions: {
                poll: false
            }
    
    或者您可以设置触发轮询的时间,如
    poll:3000
    (每3秒一次)

    另一个选项是我们可以使用和查看函数调用导致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
    

    以100%CPU持续运行是无限循环的典型特征。这在单线程NodeJ中是一个真正的问题,但不幸的是,缺少关于它的信息。尽管您声明服务器仍有响应,无限循环不是您的情况,但您仍然可以找到调试live 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
    

    …等等。

    我不使用nextTick,日志只显示正常操作。v8探查器是否会显示导致此问题的方法?除了node inspector,Profiler还有其他选项吗?链接断开、修复或删除post pleaseTim,您能解释一下为什么需要返回吗?既然函数中没有更多的命令,node就不会超出作用域吗?我已经养成了返回任何回调的习惯,这是最后一条语句。我从你那里得到这个消息。这是我的应用程序中的一个问题,因为它正在执行回调(err),而没有返回。因此,express向用户返回了一个结果,但请求仍被困在while循环中(异步版本)。@Tim您是如何通过重放历史记录来找出问题代码的?这似乎不是真正的问题。如果有一个未使用的回调,它除了占用内存之外什么也不做,那么它就会被GCed。这个可能的副本在iojs上也可以完美地工作。只需将节点prof./app.js交换为iojs--prof./app.js。目前有很多包在iojs中不起作用,它们通常会导致100%的cpu。例如,如果包的任何依赖项依赖于ncp包,那么它们可能会导致100%的cpu使用率。根据您的使用情况,您可能可以将ncp替换为。我真的非常希望这是一组可以回答我问题的步骤,但是在运行node tick processor时获得v8.log后,没有响应(cmd就在那里)如果我在chrome://tracing 模块everything只报告一堆(空)。在文本编辑器中,我看到了大量的操作(125MB的值),但我不知道如何进行交互