nodejs域如何在多个请求的幕后实际工作?

时间:2015-10-20 06:52:37

标签: javascript node.js express thread-local-storage node.js-domains

我的用例要求node.js域在请求级别跨服务器文件共享信息。

express.js中的示例实现

domain = require('domain');

app.use(function(req, res, next) {
    var reqDomain = domain.create();
    reqDomain.add(req);
    reqDomain.add(res);
    reqDomain.run(next);
});

Nodejs Domains Explicit Binding

的更多解释

控制器/服务 中 - process.domain将为您提供上面创建的域名 您可以轻松地将值绑定到此域。例如:

process.domain.obj = {};

这种解释足以理解域的用法。

问题

  1. 将域用于多个请求是否安全?

  2. 如何确保process.domain对于不同的请求是不同的而不是相同的?

  3. 我还想知道continuation local storage

    中如何处理此类问题

1 个答案:

答案 0 :(得分:4)

警告

首先 - 域名已弃用,将在即将发布的NodeJS版本中删除。我不会使用它们编写新代码。

域名如何运作?

其次 - 了解域名并不重要。他们真的是一个简单的概念。基本上,他们:

  • 包装平台中的每个异步调用(整个NodeJS API)。
  • 设置"全球"呼叫持续时间的变量。
  • 如果在该呼叫期间正在进行另一次异步呼叫 - 请记下在输入时将全局变量设置为相同的值。
  • 那就是它。

以下是如何实现域名,为了简单起见,我们只为setTimeout实施域名。

const oldTimeout = setTimeout;
setTimeout = function(fn, ms) { // also ...args, but let's ignore that
    var trackedDomain = domain;
    oldTimeout(function() { 
      var oldDomain = domain; // preserve old context
      domain = trackedDomain; // restore context to "global" variable
      fn(); // call the function itself
      domain = oldDomain; // restore old context
    }, ms); // that's it!
};

express之类的内容可以在开始时执行domain = new RequestContext,然后请求中调用的所有方法都可以使用,因为它们都像上面的示例一样包裹起来(因为它再次&# 39; s烘焙到节点本身)。

听起来很棒,为什么要删除它们?

由于他们添加的实施复杂性以及他们泄漏和错误恢复这一事实导致其无法正常工作,因此将其删除。

那我该怎么办?

您有其他选择,例如bluebird promises .bind带来了承诺链上下文,这是一种不那么漏洞的方法。

那就是说,我只是完全避免隐含的全球背景。它使重构变得困难,它使得依赖性隐含,并且使得代码更难以推理。我在创建对象时简单地将相关上下文传递给对象(简而言之,依赖注入),而不是设置全局变量。