解决方案
我正在开发模式下切换到独角兽。每一级递归都需要一个工作进程来防止死锁情况,所以我正在运行 2 个工作进程。
问题
我正在开发环境中的瘦服务器上工作。我使用端口 3000(开发环境中的默认端口)。我的问题是让服务器向自己发出请求。
假设我有以下控制器:
# app/controllers/recursions_controller.rb
class RecursionsController < ApplicationController
# /recursions
def index
# synchronously call recursions#show
RestClient.get("http://localhost:3000/recursions/1")
# finish!
render :text => 'index'
end
# /recursions/:id
def show
# finish immediately
render :text => 'show'
end
end
下面是对应的路线:
# config/routes.rb
resources :recursions
这是我最初请求时请求日志的输出recursions#index
:
[INFO] 2013-01-15 12:09:05 -0800 Started GET "/recursions" for 127.0.0.1 at 2013-01-15 12:09:05 -0800
Processing by RecursionsController#index as HTML
Completed 500 Internal Server Error in 60049ms
[FATAL] 2013-01-15 12:10:05 -0800 RestClient::RequestTimeout (Request Timeout):
app/controllers/recursions_controller.rb:8:in `index'
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.8ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.7ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (7.4ms)
[INFO] 2013-01-15 12:10:05 -0800
[INFO] 2013-01-15 12:10:05 -0800
[INFO] 2013-01-15 12:10:05 -0800 Started GET "/recursions/1" for 127.0.0.1 at 2013-01-15 12:10:05 -0800
Processing by RecursionsController#show as XML
Parameters: {"id"=>"1"}
Rendered text template (0.0ms)
Completed 200 OK in 7ms (Views: 5.5ms)
我怀疑这里发生的事情是某种僵局情况。在请求 B 返回之前,请求 A 无法返回(递归排序,无能为力),但在请求 A 返回之前无法处理请求 B(我的网络服务器中内置了明显的限制?)。当 RestClient 超时时,死锁被解决,导致异常并以 500 终止请求 A。只有这样才能处理请求 B,尽管此时它还没有实际意义。
在我看来,我的网络服务器无法处理并发请求。也就是说,这是我的问题:
我的开发环境中是否可以切换到不受这种限制的网络服务器?我们在生产环境中使用 Unicorn,它可以产生多个工作进程并因此处理并发请求,但 Unicorn 对于开发环境来说似乎太重了。使 Unicorn 成为我的问题的解决方案的同一件事可能会使读取日志输出变得困难。这是我最后的解决方案。
是否有一种巧妙的方法可以绕过明显的并发请求限制来向 Rails/Rack 框架发出请求?
任何人都可以向我提供明确说明此限制的文档吗?我不知道这是否是所有单进程 Ruby on Rails 网络服务器固有的限制,或者只是 Thin。
注意:这只是一个演示我遇到的阻塞问题的玩具问题。如果你想知道这个的真正原因,那是我将一些 HTTP 服务从我们基础设施的另一部分移动到我们的 RoR 应用程序中。我们的 RoR 应用程序在代码中的许多不同点使用这些服务,所以我试图让这些服务的客户端代码保持不变,只更改实现。这意味着发出循环 HTTP 请求。这将在以后一切稳定后进行优化。