windows getaddrinfo 响应缓慢

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1778546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:28:40  来源:igfitidea点击:

Slow response from getaddrinfo

c++windowsdnsperformancegetaddrinfo-a

提问by Nitramk

I'm using getaddrinfo to do DNS queries from C++ on Windows. I used to use the Windows API DnsQuery and that worked fine, but when adding IPv6 support to my software I switched to getaddrinfo. Since then, I've seen the following:

我正在使用 getaddrinfo 在 Windows 上从 C++ 进行 DNS 查询。我曾经使用 Windows API DnsQuery 并且效果很好,但是当向我的软件添加 IPv6 支持时,我切换到了 getaddrinfo。从那以后,我看到了以下内容:

My problem is that some times getaddrinfo take very long time to complete. The typical response from getaddrinfo takes just a few milliseconds, but roughly 1 time out of 10000, it takes longer time, in some cases around 15 seconds but there's been several cases when it takes several minutes.

我的问题是有时 getaddrinfo 需要很长时间才能完成。getaddrinfo 的典型响应只需要几毫秒,但大约 10000 次中的 1 次需要更长的时间,在某些情况下大约 15 秒,但也有一些需要几分钟的情况。

I've run Wireshark on the server and analyzed my applications debug logs and see the following:

我在服务器上运行了 Wireshark 并分析了我的应用程序调试日志并看到以下内容:

  • I call the function getaddrinfo.
  • 15 seconds later, my machine queries the DNS server.
  • Some milliseconds later, I get the response from the DNS server.
  • 我调用函数getaddrinfo。
  • 15 秒后,我的机器查询 DNS 服务器。
  • 几毫秒后,我收到了来自 DNS 服务器的响应。

The weird thing here is that the actual DNS query only takes a tenth of a second, but the time getaddrinfo actually executes is much longer.

奇怪的是,实际的 DNS 查询只需要十分之一秒,但 getaddrinfo 实际执行的时间要长得多。

The problem has been reported by many users, so it's not something specific to my machine.

很多用户都报告了这个问题,所以这不是我机器特有的问题。

So what does getaddrinfo do more than contact the DNS server?

那么 getaddrinfo 除了联系 DNS 服务器还有什么作用呢?

Edit:

编辑:

  • The problem has occurred with several addresses. If I try to reproduce the problem using these addresses, the problem does not occur.
  • I have done something stupid. Upon every DNS query, the etc/services is parsed. However, that doesn't explain a delay on several minutes. (thanks D.Shawley)
  • 问题出现在多个地址上。如果我尝试使用这些地址重现该问题,则不会出现该问题。
  • 我做了一些愚蠢的事情。在每次 DNS 查询时,都会解析 etc/services。但是,这并不能解释几分钟的延迟。(感谢 D.Shawley)

Edit 2

编辑 2

  • One type of DNS queries made by my software is anti-spam DNSBL queries. The log from one user showed me that the lookup for ip.address1.example.com always seemed to take exactly 2039 seconds, while the lookup for another.ip.address.example.com always took exactly 1324 seconds. The day after that, the lookups for those addresses were just fine. At first I thought that the DNS BL authors had put some kind of timeout on their side. But if this was the core problem, getaddrinfo should have timed out earlier?
  • 我的软件进行的一种 DNS 查询是反垃圾邮件 DNSBL 查询。一位用户的日志显示,查找 ip.address1.example.com 似乎总是需要 2039 秒,而查找 another.ip.address.example.com 总是需要 1324 秒。在那之后的第二天,对这些地址的查找就好了。起初我以为 DNS BL 作者在他们这边设置了某种超时。但如果这是核心问题,getaddrinfo应该早点超时了吧?

回答by Craig Trader

Windows has a local daemon that does DNS caching. Your call to getaddrinfo() is getting routed to that daemon, which presumably is checking its cache before submitting the query to your DNS server.

Windows 有一个执行 DNS 缓存的本地守护进程。您对 getaddrinfo() 的调用正在路由到该守护程序,该守护程序可能在将查询提交到您的 DNS 服务器之前检查其缓存。

See Windows Knowledge Base article 318803for more information on disabling the cache.

有关禁用缓存的详细信息,请参阅Windows 知识库文章 318803

[Edited]

[编辑]

It sounds to me as though your Windows Server 2003 instance is not configured correctly for IPv6. Once the IPv6 lookups timeout, it will fall back to IPv4. Knowledge Base articles that might help include:

在我看来,您的 Windows Server 2003 实例似乎没有为 IPv6 正确配置。一旦 IPv6 查找超时,它将回退到 IPv4。可能有帮助的知识库文章包括:

Unfortunately, I don't have access to any Windows Servers, so I can't test/replicate this myself.

不幸的是,我无法访问任何 Windows 服务器,因此我无法自己测试/复制它。