犀利的 Async Hooks

栏目: Node.js · 发布时间: 6年前

async_hooks 模块是Node.js 8.0中增加的特性,旨在帮助开发者追踪 Node.js 创建的异步调用资源的生命周期情况。目前此模块还处于 Experimental 阶段,不建议用于线上,不过在我们开发时会大有帮助。

Async Hooks 使用

async_hooks 的 api 很简单,使用 async_hooks.createHook(callbacks) 即可创建 initbeforeafterdestory 四个阶段的钩子回调函数。

犀利的 Async Hooks

通过以上代码,我们创建了一个可以跟踪所有异步代码的实例,默认情况下,需执行 .enable() 方法来开启对异步资源的监听。

init 回调

当异步资源被构造时,会触发 init 回调。

init 回调共有四个参数:

  1. asyncId 唯一的资源 ID。如果你在使用Node.js 10.x的 Worker ,每个线程的资源 ID 都是相互独立的。

  2. type 用于标识异步资源,Node.js内置的异步调用包括  Promise 都会有一个唯一的 type ,同时用户也可通过 API 去自定义 type

  3. triggerAsyncId 用于标识当前异步资源的调用者。

  4. resource asyncId 引用的资源。 init 被触发时,可能还未初始化完成, resource 可能无法使用

犀利的 Async Hooks

在上面代码中,假如用 console.log() 或者 process.stdout 输出,因这二者为异步操作,会导致AsyncHooks被无限调用。

运行上述代码并使用 nc localhost 8080 访问服务器三次后得到如下:

犀利的 Async Hooks

在结果中:

  1. TCPSERVERWRAP 表示我们创建的 TCP 服务器

  2. TickObject 表示 process.nextTick() ,在我们代码中 .listen() 为异步操作,调用了 process.nextTick()

  3. TCPWRAP 表示来自客户端的连接

async_hooks.executionAsyncId() 返回当前作用域的异步资源 id,代码执行时 id 从 1 开始增加。我们通过 triggerAsyncIdexecutionAsyncId 可以确定代码调用和执行顺序:

  • 程序运行时创建TCP服务器实例

    • -> 实例监听8080端口

    • -> 客户端连接当前 TCP 服务器

    • -> 客户端连接当前 TCP 服务器

    • ....

    • -> 客户端连接当前 TCP 服务器

TCPWRAPexecutionAsyncId 为0,表示此资源并非来自 JS 栈,而是由C++代码创建的。每一次的 triggerAsyncId 都相同,表示每次请求都访问的是相同的 TCP 服务器实例,我们可以根据这一特性去监控 TCP 连接情况。

before 回调

当异步操作初始化或完成后,在调用回调函数之前,将触发 before 回调。使用场景不同, before 回调调用次数也不尽相同,如 TCP 请求场景中会回调多次,文件操作 fs.open() 仅调用一次。

after 回调

回调函数执行之后会立即触发 after 回调。如异步回调执行过程中有错误产生, after 回调会在 uncaughtException 事件触发之后执行。

destory 回调

异步资源销毁,如客户端断开连接时,或 asyncResource.emitDestroy() 调用时将触发 destory 回调。

AsyncResource

默认情况下只有系统级别的异步操作才能被钩子回调追踪到,不过Node.js也为我们提供了追踪自定义的异步资源的能力。

犀利的 Async Hooks

triggerAsyncId 指定调用者资源 id,默认为当前作用域资源id。

asyncResource.runInAsyncScope(fn[, thisArg, ...args]) 会顺序触发 init 回调、调用 fn、触发 after 回调。

asyncResource.emitDestroy() 触发 destory 回调,仅能被调用一次。当资源被触发 GC 前未执行 destory ,GC 后 destory 将不再被触发,这时候容易产生内存泄露。

Async Hooks 实战

Node.js中异步代码的错误栈信息“短小且不精悍”,追踪错误时很容易让人抓狂。Async Hooks为我们提供了无侵入的处理方式。

犀利的 Async Hooks

在上面的代码中,在 init 阶段通过记录当前上下文档栈信息, uncaughtException 事件被触发时,打印额外的错误信息,并标记当前执行结果异常,我们可以在随后的 after 阶段执行如错误上报等操作。

执行结果如图:

犀利的 Async Hooks

可以看到,我们丰富了错误栈信息,并且清晰的展示了异步资源的执行情况。

小结

在 Async Hooks 出现之前,社区中也出现过类似的模块,Async Hooks 可看作这些模块的官方的支持。为了支持 Async Hooks,官方在代码中增加了很多钩子回调当调用,有兴趣可以看看提交记录,也更方便我们理解 Async Hooks。

对于开发者,我们可以用 Async Hooks 无侵入的特性监控、调试我们的代码,现在社区也出现了利用此特性的应用管理器,对开发者着实是方便不少。

参考资料

  1. Async Hooks

  2. Node.js v8.x 新特性 Async Hook 简介

犀利的 Async Hooks


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法设计与分析导论

算法设计与分析导论

R.C.T.Lee (李家同)、S.S.Tseng、R.C.Chang、Y.T.Tsai / 王卫东 / 机械工业 / 2008-1 / 49.00元

本书在介绍算法时,重点介绍用干设计算法的策略.非常与众不同。书中介绍了剪枝搜索、分摊分析、随机算法、在线算法以及多项式近似方案等相对较新的思想和众多基于分摊分析新开发的算法,每个算法都与实例一起加以介绍,而且每个例子都利用图进行详细解释。此外,本书还提供了超过400幅图来帮助初学者理解。本书适合作为高等院校算法设计与分析课程的高年级本科生和低年级研究生的教材,也可供相美科技人员和专业人七参考使用。一起来看看 《算法设计与分析导论》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具