在进行HTTP调用时,Ruby经常出现SystemExit错误

24

我有一个使用Ruby on Rails开发的网站,该网站会向外部Web服务发起HTTP请求。

大约每天一次我都会收到SystemExit错误邮件(下面是堆栈跟踪),其中对服务的某个调用失败了。如果我稍后在我的网站上尝试完全相同的查询,则可以正常工作。

自从该网站上线以来,这种问题一直存在,但我一直没有成功地找到导致它的原因。

Ruby版本是1.8.6,Rails版本为1.2.6。

是否还有其他人遇到过此类问题?

以下是错误和堆栈跟踪信息:

发生了SystemExit错误 /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in exit' /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/fcgi_handler.rb:116:in exit_now_handler' /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/inflector.rb:250:in to_proc' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in call' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in sysread' /usr/local/lib/ruby/1.8/net/protocol.rb:133:in rbuf_fill' /usr/local/lib/ruby/1.8/timeout.rb:56:in timeout' /usr/local/lib/ruby/1.8/timeout.rb:76:in timeout' /usr/local/lib/ruby/1.8/net/protocol.rb:132:in rbuf_fill' /usr/local/lib/ruby/1.8/net/protocol.rb:116:in readuntil' /usr/local/lib/ruby/1.8/net/protocol.rb:126:in readline' /usr/local/lib/ruby/1.8/net/http.rb:2017:in read_status_line' /usr/local/lib/ruby/1.8/net/http.rb:2006:in read_new' /usr/local/lib/ruby/1.8/net/http.rb:1047:in request'

/usr/local/lib/ruby/1.8/net/http.rb:945:in request_get' /usr/local/lib/ruby/1.8/net/http.rb:380:in get_response' /usr/local/lib/ruby/1.8/net/http.rb:543:in start' /usr/local/lib/ruby/1.8/net/http.rb:379:in get_response'

该错误信息来自于Ruby编程语言中的Net::HTTP模块,可能是由于在发起GET请求时出现了问题导致的。具体错误位置在第945行代码处,建议检查该处代码是否存在错误。
4个回答

9
使用fcgi和Ruby结合存在很多bug。几乎所有人都因此转向Mongrel,我建议你也这样做。

8

我有一段时间没有使用FCGI了,但我认为如果线程运行时间太长,FCGI进程可能会抛出SystemExit。这可能是Web服务没有响应,甚至是DNS查询太慢。一些谷歌搜索结果显示,Python和FCGI出现了类似的错误,因此转向mongrel是一个好主意。 这篇文章是我设置mongrel时使用的参考资料,我仍然会参考它。


5

我曾经在Apache1/fastcgi上经常遇到这种情况。 我认为这是由于fastcgi在Ruby完成之前挂起引起的。

切换到mongrel是一个不错的第一步,但还有更多工作要做。 从Web服务中剔除实时页面是一个坏主意,特别是从Rails中剔除。 Rails不是线程安全的。 您可以支持的并发连接数等于集群中的mongrels(或Passenger进程)数量。

如果您只有一个mongrel,并且有人访问调用需要10秒超时的Web服务的页面,则您网站上的每个请求都会在此期间超时。 大多数负载均衡器仅盲目循环遍历您的mongrels,因此,如果您有两个mongrels,则每隔一个请求将超时。

任何可能不可预测地变慢的事情都需要在作业队列中发生。 对/ slow / action的第一次点击将作业添加到队列中,/ slow / action将通过页面刷新或通过ajax查询保持刷新,直到作业完成,然后您从作业队列中获取结果。 如今,Rails有几个作业队列,但最古老和可能使用最广泛的是BackgroundRB

根据您的应用程序的性质,另一种选择是每N分钟通过cron从服务中剔除缓存数据,并使您的实时页面从缓存中读取。


1
我还会看看Passenger。它比Apache/nginx + Mongrel的传统解决方案容易上手得多。

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