NodeJS - 卡住/冻结时打印堆栈跟踪

use*_*017 7 node.js

当 nodejs 应用程序变得非常缓慢或冻结以获取有关性能峰值的信息时,是否可以打印它的堆栈跟踪?

在问题的重现未知的情况下,这将非常有用。

在 Java 中,这节省了数百小时,而且很简单:

  1. 产生一个新的“看门狗”线程
  2. 从主线程每 50 毫秒向看门狗发送一次心跳
  3. 如果“看门狗”在 +200 毫秒内没有收到心跳,则记录主线程堆栈跟踪

nodejs 可以实现这样的功能吗?

FI:当从 sig kill 事件启动时,nodejs 诊断报告不包含任何 javascript 堆栈跟踪。

Sim*_*gro 2

您正在寻找检查事件循环是否被阻止或缓慢。有一个 npm 包https://www.npmjs.com/package/blocked-at可以检测缓慢的同步执行并报告它的开始位置。

用法:

const blocked = require('blocked-at');

blocked((time, stack) => {
  console.log(`Blocked for ${time}ms, operation started here:`, stack)
});
Run Code Online (Sandbox Code Playgroud)

从头开始,您可以通过以下方式自己实施检查:

var interval = 500;
var interval = setInterval(function() {
    var last = process.hrtime();       
    setImmediate(function() {
        var delta = process.hrtime(last);
        if (delta > blockDelta) {
            console.log("node.eventloop_blocked", delta);
        }
    });
}, interval);
Run Code Online (Sandbox Code Playgroud)

这个想法是:如果计时器在预期时间后没有触发,这意味着事件循环在某些操作中被阻止。

此代码片段检查事件循环是否阻塞超过 500 毫秒。并不完美,我建议使用block-at来实现更强大的控制。