13

我对 Node.js 很陌生,使用 node.dns.resolveNs 函数时遇到问题。

一些域完全关闭,大约需要一分钟才能得到响应,通常是“queryNs ETIMEOUT”。我有没有办法将其设置为更短的时间,例如 10 秒?

4

5 回答 5

20

我不确定有什么方法可以直接在函数调用上设置超时,但是您可以在调用周围创建一个小包装器来自己处理超时:

var dns = require('dns');

var nsLookup = function(domain, timeout, callback) {
  var callbackCalled = false;
  var doCallback = function(err, domains) {
    if (callbackCalled) return;
    callbackCalled = true;
    callback(err, domains);
  };

  setTimeout(function() {
    doCallback(new Error("Timeout exceeded"), null);
  }, timeout);

  dns.resolveNs(domain, doCallback);
};

nsLookup('stackoverflow.com', 1000, function(err, addresses) {
  console.log("Results for stackoverflow.com, timeout 1000:");
  if (err) {
    console.log("Err: " + err);
    return;
  }
  console.log(addresses);
});

nsLookup('stackoverflow.com', 1, function(err, addresses) {
  console.log("Results for stackoverflow.com, timeout 1:");
  if (err) {
    console.log("Err: " + err);
    return;
  }
  console.log(addresses);
});

上述脚本的输出:

Results for stackoverflow.com, timeout 1:
Err: Error: Timeout exceeded
Results for stackoverflow.com, timeout 1000:
[ 'ns1.serverfault.com',
  'ns2.serverfault.com',
  'ns3.serverfault.com' ]
于 2012-05-27T22:45:07.633 回答
15

Node.jsdns.resolve*在下面使用 c-ares 库,它原生支持超时和各种其他选项。不幸的是,Node.js 没有公开这些可调参数,但其中一些可以通过RES_OPTIONS环境变量设置。

例子:RES_OPTIONS='ndots:3 retrans:1000 retry:3 rotate' node server.js

  • ndots: 与 ARES_OPT_NDOTS 相同
  • retrans: 与 ARES_OPT_TIMEOUTMS 相同
  • retry: 与 ARES_OPT_TRIES 相同
  • rotate: 与 ARES_OPT_ROTATE 相同

有关每个选项的含义的详细信息,请参见 man ares_init_options(3),例如这里http://manpages.ubuntu.com/manpages/zesty/man3/ares_init_options.3.html

于 2017-07-30T19:00:38.190 回答
1

也很高兴知道查找可能会阻止您的应用程序

我们开发了一个替换/扩展节点dns.lookup方法的模块。主要目标是绕过线程池阻塞问题。所以模块缓存响应,具有多记录解析和 TTL 支持。此外,我们还有100% 覆盖率的良好单元和功能测试。模块在生产和高负载环境中进行了测试。在麻省理工学院许可下。

这是:https ://github.com/LCMApps/dns-lookup-cache

我相信它可能会有所帮助!

于 2019-03-25T17:19:55.427 回答
0

基于@redbaron 的回答,您可以在运行时设置 RES_OPTIONS 变量,以设置以下所使用的 c-ares 库的超时dns.resolve*

// this will timeout for (1000 * 3 * 2) ms
process.env.RES_OPTIONS='ndots:3 retrans:1000 retry:3 rotate';
于 2021-03-12T14:43:34.117 回答
0

具有超时的 resolveNs 包装器:

const dns = require("dns");

const nsLookup = (domain, timeout) => {
  return new Promise((resolve, reject) => {
    let finished = false;

    const timer = setTimeout(()=>{
      finished = true; 
      reject();
    }, timeout);

    const callback = (_err, result) => {
      clearTimeout(timer);
      if (!finished) resolve(result);
    };
  
    dns.resolveNs(domain, callback);  
  });
};
于 2022-02-06T16:38:08.430 回答