我对 Node.js 很陌生,使用 node.dns.resolveNs 函数时遇到问题。
一些域完全关闭,大约需要一分钟才能得到响应,通常是“queryNs ETIMEOUT”。我有没有办法将其设置为更短的时间,例如 10 秒?
我对 Node.js 很陌生,使用 node.dns.resolveNs 函数时遇到问题。
一些域完全关闭,大约需要一分钟才能得到响应,通常是“queryNs ETIMEOUT”。我有没有办法将其设置为更短的时间,例如 10 秒?
我不确定有什么方法可以直接在函数调用上设置超时,但是您可以在调用周围创建一个小包装器来自己处理超时:
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' ]
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
也很高兴知道查找可能会阻止您的应用程序。
我们开发了一个替换/扩展节点dns.lookup
方法的模块。主要目标是绕过线程池阻塞问题。所以模块缓存响应,具有多记录解析和 TTL 支持。此外,我们还有100% 覆盖率的良好单元和功能测试。模块在生产和高负载环境中进行了测试。在麻省理工学院许可下。
这是:https ://github.com/LCMApps/dns-lookup-cache
我相信它可能会有所帮助!
基于@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';
具有超时的 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);
});
};