在Ruby中缓存DNS查询

8
我们在Ruby中使用rest-client gem来自动化测试我们的REST API。但是我注意到,它在每次请求时都会为主机名进行DNS查找。在本地环境中,如果使用"localhost",测试运行得很快,但是如果使用正确的主机名,则需要2.5倍的时间,执行大量的DNS查找。
我认为这个问题与rest-client无关,而是基于Ruby的网络编程。我尝试了要求使用'resolv'和'resolv-replace',但是它们没有起到帮助作用。'dig'报告DNS查询具有1小时的TTL。
是否有一种方法可以使Ruby缓存DNS请求? 我可以更改代码以显式使用IP地址,但那是修复问题的错误位置。
我正在运行Ubuntu 12.04和Ruby 1.9.3。

我也对DNS查询缓存感兴趣。你能让它工作吗? - Jong Bor Lee
还没有找到方法。我们通过使用IP地址来解决了这个问题。 - Sampo
可能的解决方案:https://dev59.com/9mgu5IYBdhLWcg3w3ara - Kelvin
4个回答

2
我在寻找Ruby DNS缓存以及resolv.rb如何使用TTL缓存DNS请求时找到了这个问题。
resolv.rb的API中,发现DNS记录的TTL有点隐蔽,但它看起来像这样:
def get_ip(hostname)
  dns = Resolv.new
  redis = Redis.new # storing in redis
  ip = redis.get("ip:#{hostname}") 
  return ip unless ip.nil?
  begin
    resource = dns.getresource(hostname, Resolv::DNS::Resource::IN::A)
  rescue Resolv::ResolvError
    return false
  end
  # storing in redis for only as long as the TTL allows
  redis.setex("ip:#{hostname}", resource.address.ttl, resource.address.to_s)
  resource.address.to_s # IP address as string
end

Gist

注意:使用Redis作为缓存。


2
你可以使用dnsruby宝石来将名称解析为地址,然后在调用中使用该地址。
#! /usr/bin/env ruby

# Gets the IP address of a host.

require 'dnsruby'  # gem install dnsruby first, of course

def hostname_to_ip_addr(host_name)
  query = Dnsruby::Message.new(host_name)
  response = Dnsruby::Resolver.new.send_message(query)
  response.answer[1].address
end

host_name = 'cnn.com'
ip_addr = hostname_to_ip_addr(host_name)
puts("Host name: #{host_name}, IP address: #{ip_addr}")

original code from this Gist


欢迎来到Stack Overflow!虽然这个回答可能解决了问题,但是为了以后更好地参考,请在此处包含答案的关键部分,并提供链接作为参考。(看起来有人可能已经在帮你编辑代码了。) - Nathan Tuggy

1

操作系统通常提供一些DNS名称缓存,但并不总是启用。

据我了解,Ruby使用libc来解析名称。因此,这可能会按进程缓存响应。但我对libc并不完全确定。

您可以尝试的一个可能的解决方法是在Ruby程序中手动解析主机名为IP地址,然后对同一主机进行重复请求时使用返回的IP地址。

但这对于连接到SSL目标可能不起作用。证书验证通常取决于匹配主机名。

也许有一个很好的Ruby网络套接字gem,不使用Net :: HTTP,并将保留自己的DNS缓存。


0

我刚刚查看了rest-client的代码,它只是使用了Net::HTTP,而Net::HTTP又使用了Socket。

然后一切都消失在Ruby解释器实现中,这就是我的知识有点薄弱的地方(行为可能会因为你使用的是MRI、JRuby等不同的解释器而有所不同)。

我希望DNS解析最终会转交给操作系统,所以也许你的问题是由于主机上一些奇怪的解析器配置引起的?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接