2016-03-09 3 views
2

У меня есть этот кусок кода ruby, который работает прерывисто, я могу называть его в оболочке несколько раз ctrl-c-ing, когда он зависает, и он будет работать мгновенно половину времени и вечно вешать другая половина.Ruby DNS-разрешение зависает каждый раз

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

Я пробовал ваш код и не могу воспроизвести проблему. Обратите внимание, что для вашего конкретного примера ответ не всегда одинаковый, что имеет смысл для 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, и может быть задействован некоторый локальный кеш. Вы должны попробовать протестировать свой DNS, возможно, с помощью команды и проверить, действительно ли ответы на самом деле поступают с DNS-сервера, а не из кеша.

В вашем коде, вы можете захотеть включить тайм-аут, например:

dns.timeouts = 3 
+1

Проблема была в снаружи действительно, команда привязки хоста() перед тем, чтобы соединить() с и, следовательно, получает порт источника в диапазон, определенный в/proc/sys/net/ipv4/ip_local_port_range, но сам ruby ​​делает соединение напрямую, а некоторые из случаев, когда выделенный порт источника оказался из того, что искал брандмауэр при ответах. –

Смежные вопросы