如何调试导致 100% cpu 使用的 node.js?
Posted
技术标签:
【中文标题】如何调试导致 100% cpu 使用的 node.js?【英文标题】:how to debug node.js causing 100% cpu usage? 【发布时间】:2012-04-16 00:41:26 【问题描述】:我有一个使用 express 和 redis 的节点应用程序。在我们的开发服务器上,经过一段时间的使用 node 开始使用 100% cpu。应用程序仍然响应,但顶部报告节点使用 100%。在节点重新启动之前,cpu 不会下降。
我没有将其确定为导致它的任何特定路线或功能。
诊断此问题的最佳方法是什么?
我使用 v8-profiler 查看了 node-inspector,它给出了与此处报告的相同的错误 https://github.com/dannycoates/v8-profiler/issues/10
【问题讨论】:
node js cpu 100%的可能重复 【参考方案1】:您可以使用node-tick 分析您的应用。
-
由
sudo npm -g install tick
安装node-tick
使用启用的配置文件 node --prof ./app.js
运行您的应用程序
在 CPU 使用率达到 100% 的一段时间后停止您的应用
您可以在您的应用目录中看到 v8.log,现在您可以使用 node-tick-processor 读取它
运行node-tick-processor
并解释结果
将 v8.log 加载到 chrome://tracing 中以进行树分析。
node js cpu 100%
【讨论】:
这也适用于 iojs。只需将 node --prof ./app.js 换成 iojs --prof ./app.js。有很多包目前在 iojs 中不起作用,而且它们通常会导致 100% cpu。例如,如果您的包的任何依赖项依赖于 ncp 包,那么它们可能会导致 100% 的 CPU 使用率。根据您的用例,您可以将 ncp 换成 npmjs.com/package/ember-cli-copy-dereference。 我真的,真的希望这是一组可以回答我的问题的步骤,但是当我运行 node-tick-processor 时获得 v8.log 后没有响应(cmd 只是坐在那里) 并且如果我在 chrome://tracing 模块中打开相同的日志文件,则所有内容都只会报告一堆(空)。在文本编辑器中,我看到大量操作(价值 125MB),但我不知道如何解释这些信息。【参考方案2】:我通过编写脚本记录每个请求然后重放它们来发现问题。
问题是因为我有一个未返回的回调。
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();
);
这很酷,因为播放的每个历史项目都会再次添加到队列中,因此它会不断循环,并且每次您访问新页面时,都会将其添加到队列中。
【讨论】:
Tim,你能解释一下为什么需要退货吗?由于函数中没有更多命令,节点不会只是超出范围吗? 我已经养成了返回最后一个语句的任何回调的习惯。我从stella.laurenzo.org/2011/03/bulletproof-node-js-coding 得到这个提示。这是我的应用程序中的一个问题,因为它正在执行回调(错误)而没有返回。因此,express 向用户返回了结果,但请求仍被困在 while 循环(异步版本)中。 @Tim 你是如何通过回放历史找出问题代码的? 这似乎不是真正的问题。如果有一个未使用的回调,除了占用内存什么都不做,那么它就会被 GCed。【参考方案3】:持续以 100% CPU 运行是无限循环的典型特征。这是单线程 nodejs 中的一个真正问题,但不幸的是,它缺乏相关信息。尽管您声明您的服务器仍然响应并且无限循环不是您的情况,但您仍然可以找到调试实时 nodejs 应用程序的有用提示。
最终我找到了唯一有用的article: 如何在 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
……等等。
【讨论】:
【参考方案4】:如果您使用带有 webpack 的 UI 应用程序,请注意 watchOptions
或 watch
。
对我来说,禁用民意调查可以解决问题
watchOptions:
poll: false
或者您可以设置一个时间,当投票将被触发,如poll: 3000
(每 3 秒一次)
https://webpack.js.org/configuration/watch/#watchoptionsignored
【讨论】:
【参考方案5】:在我关闭超级用户模式之前,我也经历了 100% 的 CPU 使用率(导致节点重新启动,当文件更改时)。
这可能无法回答这个问题,但如果像我这样的新手担心 CPU 使用率,可能就是这种情况。
【讨论】:
【参考方案6】:如果您使用nodemon
来监视您的文件,请考虑使用文件较少的文件夹的路径。例如让nodemon
watch 使用 bower 或 npm 安装的库文件夹会导致 CPU 使用率很高,因为其中包含数千个文件。
这是我的示例nodemon.json
文件:
"watch": ["views","routes"],
"ext": "html, js"
像魅力一样工作。
【讨论】:
【参考方案7】:也许您在某处使用 nextTick
进行了一些计算,这会不断地浪费 CPU。
如果您无法运行配置文件,那么很难找出哪个方法正在破坏 CPU。另一件事是通过使用记录器中间件http://senchalabs.github.com/connect/middleware-logger.html来检查快速日志
【讨论】:
我不使用 nextTick 并且日志只是显示正常操作。 v8 分析器会显示导致它的方法吗?除了节点检查器之外,分析器还有其他选项吗? 链接损坏,请修复或删除帖子【参考方案8】:另一种选择是我们可以使用Flame Graph 并查看函数调用导致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
【讨论】:
【参考方案9】:这可能是因为您直接使用了大量文件。例如node_modules 文件夹。
您需要使用 -i 参数来忽略该文件夹。所以它应该是这样的:
supervisor -i ./node_modules app
.
【讨论】:
以上是关于如何调试导致 100% cpu 使用的 node.js?的主要内容,如果未能解决你的问题,请参考以下文章
求php-cgi.exe使用率过高导致CPU100%的解决办法
如何找出 Node.js 服务器 CPU 100% 的原因?