Debugging 如何调试node.js导致100%的cpu使用率?
我有一个使用express和redis的节点应用程序。在我们的开发服务器上,经过一点使用之后,node开始使用100%的cpu。应用程序仍有响应,但top使用100%报告节点。在重新启动节点之前,cpu不会下降 我并没有把它和导致它的任何特定路线或功能联系起来 诊断此问题的最佳方法是什么 我用v8探查器查看了节点检查器,它给出了与此处报告的相同的错误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。还有
也许你在某个地方使用了
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
bysudo npm-g安装tick
节点运行应用程序--prof./app.js
节点勾选处理器
并解释结果我也经历了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的值),但我不知道如何进行交互