getaddrinfo:未提供节点名或服务名,或者未知

78
我有一个Ruby on Rails应用程序,我正在部署到运行Mac OS X 10.6的计算机上。问题出现在由delayed_job运行的代码中。只有当通过delayed_job运行时才会出现问题。如果我在控制台中运行它(rails console production)或直接通过cURL调用API,它就可以正常工作。此外,在我的开发环境中整个过程都没有问题。
基本上,代码在一个地方能够正常工作,但在必须工作的地方却失败了。我已经搜索并找到了一些资源,但是没有建议适用或有任何区别。当我登录服务器并运行命令时,一切都正常。但由于某种原因,当它们由Capistrano运行/启动时,它不起作用。
非常感谢您的帮助。
重要说明:
- Ruby版本:1.9.2-p0 - Rails版本:3.0.1 - delayed_job版本:最新(来自collectiveidea/delayed_job) - rest-client版本:1.6.1
代码:
class CallApi < Struct.new(:num)
  def perform
    log "Entering perform"
    apinum = num || 5
    log "ApiNum = #{apinum}"
    results = attempt(2,10) do
      ActiveSupport::JSON.decode(RestClient.get(API_URL, {:params => {:apinum => apinum}}))
    end
    log "Results retrieved. (count: #{results.count})"
  end

  def log(message)
    Delayed::Worker.logger.info "[CallApi] #{Time.now} - #{message}"
  end
end

环境配置(注意:URL是虚假的,但与真实URL的格式相同):

API_URL = "http://api.example.org/api_endpoint"
# Originally, I had "http://" before the beginning, but found a
# post mentioning that Net::Http.start didn't like that.
# So I tried it both ways.
# The same error occurs regardless of if the "http://" is there.

调用发生错误的位置:

RestClient.get(API_URL, {:params => {:apinum => apinum}})

错误:

getaddrinfo: nodename nor servname provided, or not known
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:644:in `initialize'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:644:in `open'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:644:in `block in connect'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/timeout.rb:44:in `timeout'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/timeout.rb:87:in `timeout'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:644:in `connect'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:637:in `do_start'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/net/http.rb:626:in `start'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/rest-client-1.6.1/lib/restclient/request.rb:166:in `transmit'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/rest-client-1.6.1/lib/restclient/request.rb:60:in `execute'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/rest-client-1.6.1/lib/restclient/request.rb:31:in `execute'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/rest-client-1.6.1/lib/restclient.rb:68:in `get'
/private/var/www/project-gemset/releases/20101109002137/lib/call_api.rb:7:in `block in perform'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/attempt-0.2.0/lib/attempt.rb:70:in `attempt'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/attempt-0.2.0/lib/attempt.rb:114:in `attempt'
/private/var/www/project-gemset/releases/20101109002137/lib/call_api.rb:6:in `perform'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/backend/base.rb:77:in `invoke_job'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:118:in `block (2 levels) in run'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/timeout.rb:57:in `timeout'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:118:in `block in run'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:117:in `run'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:176:in `reserve_and_run_one_job'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:102:in `block in work_off'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:101:in `times'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:101:in `work_off'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:76:in `block (2 levels) in start'
/Users/api/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:75:in `block in start'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:72:in `loop'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/worker.rb:72:in `start'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:100:in `run'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:79:in `block in run_process'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `call'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `block in start_proc'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call_as_daemon'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application.rb:254:in `start_proc'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application.rb:294:in `start'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application_group.rb:159:in `block (2 levels) in start_all'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application_group.rb:158:in `fork'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application_group.rb:158:in `block in start_all'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application_group.rb:157:in `each'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/application_group.rb:157:in `start_all'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/controller.rb:80:in `run'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons.rb:193:in `block in run_proc'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `call'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `catch_exceptions'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/gems/daemons-1.1.0/lib/daemons.rb:192:in `run_proc'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:78:in `run_process'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:72:in `block in daemonize'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:70:in `times'
/Users/api/.rvm/gems/ruby-1.9.2-p0@project-gemset/bundler/gems/delayed_job-aba9905764c2/lib/delayed/command.rb:70:in `daemonize'
script/delayed_job:5:in `'

我在尝试通过Postmark发送电子邮件时突然收到了这条消息。结果发现他们的DNS出现了问题,无法解析,因此这就是我们的Rails应用程序上出现的错误。 - Joshua Pinter
13个回答

55

当 DNS 解析失败时,便会出现该错误。请检查您是否可以使用命令行 wget(或 curl)api URL。更改 DNS 服务器并进行测试可能会有所帮助。


3
虽然技术方面可能出了问题,但我仍然不知道为什么会发生这种情况。当我登录服务器并运行命令时,一切正常。但出于某种原因,当它们由Capistrano运行/启动时,它就无法正常工作。由于我没有找到任何解决方法,我将接受这个答案并给其他人投票。 - ChronoPositron
4
从睡眠中唤醒我的 Mac,运行了一些 Cucumber 测试,然后出现了这个错误。我把 wifi 开关切换了一下,然后它就好了。看起来确实与 DNS 有关,但这样修复了它。 - Matt Vukas
1
帮助检查是否需要设置任何HTTP代理。 - OkraSala

10

rest-client的RestClient在解析URL时需要包含http:协议头。它会自动调用Net::HTTP,但是Net::HTTP不需要http:部分。不过rest-client已经处理好了这个问题。

你要访问的URL是实际存在的吗?example.org是一个用于测试和文档编写的有效域名,并且可以被访问。如果我尝试访问"api"和"api_endpoint"部分时,我预计会失败并看到错误提示。

require 'socket'

IPSocket.getaddress('example.org') # => "2620:0:2d0:200::10"
IPSocket.getaddress('api.example.org') # => 
# ~> -:7:in `getaddress': getaddrinfo: nodename nor servname provided, or not known (SocketError)
# ~>    from -:7:in `<main>'

以下是使用Curl工具获得的结果:
greg-mbp-wireless:~ greg$ curl api.example.org/api_endpoint
curl: (6) Couldn't resolve host 'api.example.org'
greg-mbp-wireless:~ greg$ curl example.org/api_endpoint
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /api_endpoint was not found on this server.</p>
<hr>
<address>Apache Server at example.org Port 80</address>
</body></html>
greg-mbp-wireless:~ greg$ curl example.org
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
  <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  <TITLE>Example Web Page</TITLE>
</HEAD> 
<body>  
<p>You have reached this web page by typing &quot;example.com&quot;,
&quot;example.net&quot;,&quot;example.org&quot
  or &quot;example.edu&quot; into your web browser.</p>
<p>These domain names are reserved for use in documentation and are not available 
  for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 
  2606</a>, Section 3.</p>
</BODY>
</HTML>

我在问题中提到的API_URL只是一个假的示例URL,其格式与真实的URL相同。直接在服务器上运行这些命令并使用真实的URL返回了我所期望的一切。似乎问题只发生在通过Capistrano启动delayed_job时。(我将编辑问题以便注意到这一点) - ChronoPositron
啊,好的。example.com及其相关网站是用于文档编写的,但很多人尝试将其用于测试,这样做并不能让他们走得太远。 - the Tin Man

10

我通过简单地关闭并重新打开终端来解决了这个问题。


在我的情况下,nslookupdig 都能正常工作,但是 curl 不能。完全退出我的 MacBook 的 Terminal 应用程序(实际上,我使用的是 Iterm2 应用程序),然后重新启动它解决了问题。 - Vincent Yin

10

今天我遇到了一个类似的情况——将应用部署到Mac OS X服务器时,当我尝试访问外部API时收到了“getaddrinfo”消息。事实证明,当最初启动应用程序的ssh会话不再活动时,就会发生此错误。这就是为什么如果您通过ssh登录到服务器并手动运行命令(或手动启动服务器),则一切都可以正常工作——只要保持ssh会话处于活动状态,就不会出现此错误。

我不确定这是否是OS X中的错误或特殊情况。以下是带领我找到解决方案的页面- http://lists.apple.com/archives/unix-porting/2010/Jul/msg00001.html

我所要做的就是更新我的Capistrano任务以使用“nohup”启动应用程序。因此,更改前的代码如下:

run "cd #{current_path} && RAILS_ENV=production unicorn_rails -c config/unicorn.rb -D"
为了更好地满足您的需求,我需要知道需要翻译的具体内容是什么。 "

to

" 只是一个 HTML 标记,它本身没有任何含义。请提供更多的上下文和信息,这样我才能够为您提供准确的翻译。
run "cd #{current_path} && RAILS_ENV=production nohup unicorn_rails -c config/unicorn.rb -D"

这对我起了作用。

希望这能帮助某人——我曾经非常痛苦地弄清楚它!


对于那些在使用resque时遇到问题的人,你可以使用nohup运行rake命令来解决这个问题。例如:bundle exec nohup rake resque:work。感谢Joshua! - ipd

6
为了避免这个问题,我们可以绑定到127.0.0.1而不是localhost:

bin/rails server -b 127.0.0.1


这对我有效,但为什么更改hosts文件不能解决问题?有关原因的任何想法吗? - rangeOShun
@rangeOShun 我也无法弄清楚。我的一个macOS总是有这个问题,不仅仅是针对Rails,而是所有其他的情况。 - David Zhang
更新:实际上我尝试了几次解决它,但不幸的是都失败了。重新安装macOS就可以了。哈哈 - David Zhang

6

当我检查hosts文件时,发现localhost未设置,导致出现了同样的错误。将localhost设置为127.0.0.1后问题得以解决。

sudo vi /etc/hosts
>>

127.0.0.1       localhost

5

我重新启动了我的电脑(Mac Mountain Lion),问题得到了解决。我认为与shell认为自己已经断开了与互联网的连接有关。

以某种明确的方式重新启动您的shell也可能解决此问题。然而,仅仅打开一个新的会话/窗口并没有起作用。


断开您的WiFi/以太网连接并重新连接可能也会起作用。 - coloradoblue
我尝试了sudo postfix start却一直报错。重新启动mac就解决了。 - kk1957
是的,当我开启或关闭 VPN 时偶尔会发生这种情况。打开一个新的终端窗口就可以解决它。 - Jeremy Murray

2
我看到了一个与Rails无关的错误。原来我的测试试图使用一个端口号太高(大于65535)。
这段代码会产生上述错误。
require 'socket'
Socket.getaddrinfo("127.0.0.1", "65536")

不是这个问题。 - IIllIIll

2

对我来说,为了让rspec测试运行起来,我不得不在我的 local_env.yml 中更改一行代码。

我最初写的是:

REDIS_HOST:'redis'

然后我将其更改为:

REDIS_HOST:'localhost'

这样测试就可以正常运行了。

"Original Answer"翻译成"最初的回答"。


1
在我的config/application.yml文件中,我已经更改了这个。
redis:
    url: "redis://redis:6379/0"

到这里

redis:
    url: "redis://localhost:6379/0"

它对我来说可行


我忘记在更改后执行redis实例...哭啊...如果redis在本地环境中,则这是正确的。 - V-SHY

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