jjzjj

c++ - getaddrinfo 响应缓慢

coder 2023-11-10 原文

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

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

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

  • 我调用函数 getaddrinfo。
  • 15 秒后,我的机器查询 DNS 服务器。
  • 几毫秒后,我从 DNS 服务器收到响应。

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

这个问题已经被许多用户报告过,所以它不是我机器特有的问题。

那么 getaddrinfo 除了联系 DNS 服务器还做了什么?

编辑:

  • 有几个地址出现了问题。如果我尝试使用这些地址重现问题,则问题不会发生。
  • 我做了一些蠢事。在每次 DNS 查询时,都会解析 etc/services。但是,这并不能解释几分钟的延迟。 (感谢 D.Shawley)

编辑 2

  • 我的软件进行的一种 DNS 查询是反垃圾邮件 DNSBL 查询。一位用户的日志告诉我,查找 ip.address1.example.com 似乎总是恰好需要 2039 秒,而查找 another.ip.address.example.com 总是恰好需要 1324 秒。在那之后的一天,对这些地址的查找就好了。起初我以为 DNS BL 作者在他们这边设置了某种超时。但如果这是核心问题,getaddrinfo 应该更早超时?

最佳答案

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

参见 Windows Knowledge Base article 318803有关禁用缓存的更多信息。

[已编辑]

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

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

关于c++ - getaddrinfo 响应缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1778546/

有关c++ - getaddrinfo 响应缓慢的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  3. ruby - Mechanize 的 getaddrinfo 错误 - 2

    我编写了一个脚本,它将遍历我们数据库中的所有客户,验证他们的网站URL是否有效,并尝试在他们的主页上找到一个Twitter链接。我们有超过10,000个URL需要验证。在url验证一小部分后,我们开始收到每个URL的getaddrinfo错误。这是抓取单个URL的代码副本:defscrape_url(url)url_found=falsetwitter_name=nilbeginagent=Mechanize.newdo|a|a.follow_meta_refresh=trueendagent.get(normalize_url(url))do|page|url_found=truet

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐