当有大量要解析的CNAME时,dns.resolveCname失败

时间:2017-11-01 06:50:22

标签: node.js dns nslookup

我正在编写一个解决大约10,000个CNAME的程序。

我遇到的问题是,当要解析的CNAME数量过大时,dns.resolveCname()会返回Error: queryCname ESERVFAIL错误。

代码如下所示:

const dns = require('dns')
dns.setServers(['8.8.8.8']) // provided by google

let cnames = [....] // length of cnames is 10,000
let promiseArr = []

for (let i = 0; i < cnames.length; i += 1) {
  let p = new Promise((resolve, reject) => {
    dns.resolveCname(cnames[i], (err, records) => {
      if (err) {
        console.log(err)  // this line generates Error: queryCname ESERVFAIL
        resolve()         // sorry, I forgot adding this line.
      } else {
        console.log(records)
        resolve()         // sorry, I forgot adding this line.
      }
    })
  })
  promiseArr.push(p)
}

Promise.all(promiseArr)
.then(value => {
  console.log(`Promise.all done`)
})
.catch(err => {
  console.log(`promise err: ${err}`)
})

这是否意味着我不能太频繁地使用dns.resolveCname()

是否可以通过降低I触发dns.resolveCname()的频率来避免此问题?

或者我还有其他方法可以克服这个问题吗?

我正在使用node.js v6.2.2。

1 个答案:

答案 0 :(得分:0)

  

ESERVFAIL - 应用程序查询api.example.com,抛出SERVFAIL错误并且调用失败。

如果至少有一个异步函数抛出错误,

Promise.allcatch(停止执行)。所以在这种情况下你不能使用Promise all,对于10000异步调用来说这是一个不好的做法,你可以很容易地把所有内存都丢弃。

解决问题的一种方法是实现parallel limited queue来解决错误和结果,然后您就可以设法以正确的方式输出结果。

我找到的一个实现有限队列的库是cwait

  

从他们的文件:

import * as Promise from 'bluebird';
import {TaskQueue} from 'cwait';

/** Queue allowing 3 concurrent function calls. */
var queue = new TaskQueue(Promise, 3);

Promise.map(list, download); // Download all listed files simultaneously.

Promise.map(list, queue.wrap(download))); // Download 3 files at a time.