我有这段间歇性的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
命令时,它总会返回立即
如何以可预测的方式完成这项工作?
答案 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