Ruby DNS解析每隔一段时间就会挂起

时间:2016-03-09 11:01:31

标签: ruby dns resolution hang

我有这段间歇性的ruby代码,我可以在shell中多次调用它,当它挂起时它会瞬间工作一半时间并永远挂起另一半。

require 'resolv'
puts "initializing"
txt = Resolv::DNS.open do |dns|
    records = dns.getresources("www.google.com", Resolv::DNS::Resource::IN::A)
    records.empty? ? nil : records.map{|rec| rec.address}.compact
end
puts "records are #{txt}"

这是我在两种情况下看到的输出

[ ~]$ ruby test.rb 
initializing
records are 216.58.217.132
[ ~]$ ruby test.rb 
initializing
records are 216.58.217.132
[ ~]$ ruby test.rb 
initializing

^C/usr/lib/ruby/1.8/resolv.rb:620:in `select': Interrupt
        from /usr/lib/ruby/1.8/resolv.rb:620:in `request'
        from /usr/lib/ruby/1.8/resolv.rb:489:in `each_resource'
        from /usr/lib/ruby/1.8/resolv.rb:975:in `resolv'
        from /usr/lib/ruby/1.8/resolv.rb:973:in `each'
        from /usr/lib/ruby/1.8/resolv.rb:973:in `resolv'
        from /usr/lib/ruby/1.8/resolv.rb:972:in `each'
        from /usr/lib/ruby/1.8/resolv.rb:972:in `resolv'
        from /usr/lib/ruby/1.8/resolv.rb:970:in `each'
        from /usr/lib/ruby/1.8/resolv.rb:970:in `resolv'
        from /usr/lib/ruby/1.8/resolv.rb:481:in `each_resource'
        from /usr/lib/ruby/1.8/resolv.rb:468:in `getresources'
        from test.rb:4
        from /usr/lib/ruby/1.8/resolv.rb:307:in `open'
        from test.rb:3

我知道DNS是一种外部服务,它可能是不稳定的,但这并不能解释它如何能够立即工作并在其他时间永远挂起,而且,当我使用host www.google.com命令时,它总会返回立即

如何以可预测的方式完成这项工作?

1 个答案:

答案 0 :(得分:1)

我尝试了您的代码,无法重现该问题。请注意,对于您的特定示例,响应并不总是相同,这对www.google.com有意义。

tmp> ruby resolv.rb
# initializing
# records are [#<Resolv::IPv4 216.58.211.100>]

tmp> ruby resolv.rb
# initializing
# records are [#<Resolv::IPv4 74.125.136.105>, #<Resolv::IPv4 74.125.136.106>, #<Resolv::IPv4 74.125.136.147>, #<Resolv::IPv4 74.125.136.99>, #<Resolv::IPv4 74.125.136.103>, #<Resolv::IPv4 74.125.136.104>]

我认为您遇到的问题不在您的代码之内。 host命令比发出DNS请求更多。它还会检查/etc/hosts文件,并且可能涉及一些本地缓存。您应该尝试使用dig命令测试DNS,并检查答案是否真的总是来自DNS服务器,而不是来自缓存。

在您的代码中,您可能希望启用超时,例如:

dns.timeouts = 3