异步函数上下文跟踪AsyncLocalStorage
发布于 3 年前 作者 dbit-xia 18734 次浏览 来自 问答

好像没有人讨论过trace相关的话题,感觉很实用呢 nodejs支持异步函数获取上下文的跟踪了,这个有坑吗 class AsyncLocalStorage

const http = require('http');
const { AsyncLocalStorage } = require('async_hooks');

const asyncLocalStorage = new AsyncLocalStorage();

function logWithId(msg) {
  const id = asyncLocalStorage.getStore();
  console.log(`${id !== undefined ? id : '-'}:`, msg);
}

let idSeq = 0;
http.createServer((req, res) => {
  asyncLocalStorage.run(idSeq++, () => {
    logWithId('start');
    // Imagine any chain of async operations here
    setImmediate(() => {
      logWithId('finish');
      res.end();
    });
  });
}).listen(8080);

http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
//   0: start
//   1: start
//   0: finish
//   1: finish
9 回复

是好东西,midway-hooks就用了它

有坑,这个东西用起来很爽,修BUG非常恶心。 我这边之前有个人日志系统就是用这个,现在出BUG了,只能重写他这块了。

我们内部的项目大量使用了这个特性,用来实现另一种依赖注入。

@xcfox 开源了吗?分享一下

@i5ting 赞, 那感觉就稳了

@zy445566 ~~打算简单用, 只用来记录上下文的traceid感觉应该可靠

@dbit-xia 我这边就是记录上下文的traceid出问题了,建议直接使用请求上下文req绑定traceid。 如果你用async_hooks来记录traceid就要保证,你这个中间件是第一个执行,因为async_hooks原理就是坚定某个回调里面的全关联。 而且你这个traceid作为了全局唯一值,真的很容易出错。

@zy445566 所以啥问题?是丢了还是说混了?req绑定traceid是指一直把req往下传递吗?还有为什么要第一个执行?可以上代码看看吗?到底出了啥问题?

@luanxuechao 因为只有第一个中间件,里面的next才是包括全部中间件的,我这边的async_hook的traceid绑定的是asyncId,所以问题很大。如果是绑定req那只有在之前的中间件获取不到traceid也就还好了

回到顶部