【问题标题】:Caching DNS queries in Ruby在 Ruby 中缓存 DNS 查询
【发布时间】:2012-05-15 08:10:37
【问题描述】:

我们正在使用 Ruby 中的 rest-client gem 来自动测试我们的 REST API。但是我注意到,在它发出的每一个请求中,它都会对主机名进行 DNS 查找。在本地环境中,如果使用“localhost”,则测试运行速度很快,但如果使用正确的主机名,则需要 2.5 倍的时间,执行大量 DNS 查找。

我相信这个问题与 rest-client 无关,而是与基础 Ruby 网络有关。我试过要求'resolv'和'resolv-replace',但它们没有帮助。 'dig' 报告 DNS 查询的 TTL 为 1 小时。

有没有办法让 Ruby 缓存 DNS 请求?我可以更改代码以明确使用 IP 地址,但这是解决问题的错误位置。

我正在运行 Ubuntu 12.04 和 Ruby 1.9.3。

【问题讨论】:

标签: ruby caching dns


【解决方案1】:

您可以使用 dnsruby gem 将名称解析为地址,然后在调用中使用该地址。

#! /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}")

来自Gist的原始代码

【讨论】:

  • 欢迎来到 Stack Overflow!虽然这可能会回答问题,it would be preferable in future 在此处包含答案的基本部分,并提供链接以供参考。 (看起来有人可能已经在为你编辑代码了。)
【解决方案2】:

我在寻找 ruby​​ dns 缓存以及 resolv.rb 如何使用 TTL 来缓存 dns 请求时遇到了这个问题。

发现一条dns记录的TTL有点隐藏在resolv.rb的api中,但看起来有点像这样:

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 作为缓存。

【讨论】:

    【解决方案3】:

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

    据我了解,ruby 使用 libc 来解析名称。所以这可能会缓存每个进程的响应。不过,我并不完全确定 libc。

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

    不过,这可能不适用于与 SSL 目标的连接。证书验证通常取决于匹配主机名。

    也许有一个不错的 ruby​​ 网络套接字 gem,它不使用 Net::HTTP 并且会保留它自己的 DNS 缓存。

    【讨论】:

      【解决方案4】:

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

      然后一切都消失在 Ruby 解释器实现中,这是我的知识有点薄弱的地方(并且行为可能会根据您是否使用 MRI、JRuby 等而改变)

      我希望 DNS 解析最终会推迟到操作系统,所以也许您的问题归结为主机上的一些奇怪的解析器配置?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-16
        • 1970-01-01
        • 1970-01-01
        • 2010-12-22
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多