23

准备测试: sleep 10在行动中

测试: 在浏览器中打开两个标签页访问动作

结果: 当第二个请求运行时,第一个请求完成并开始渲染视图,但视图仍然是空白的。在第二个请求也完成后,这两个请求同时完成了视图的渲染。

结论: Rails 只是一个实例。一个请求只有在前一个请求完成后才能进入动作。但是如何解释响应部分?为什么多个请求同时完成视图的渲染?

4

3 回答 3

24

WEBrick 是多线程的,但 Rails 开发人员硬编码了一个互斥锁,因此它一次只能处理一个请求。你可以猴子补丁Rails::Server,你可以自由地运行一个多线程的 WEBrick。

请注意,WEBrick 只有在 configconfig.cache_classes = true和时才会是多线程config.eager_load = true的,这对于RAILS_ENV=production. 这是因为开发中的类重载不是线程安全的。

要在 Rails 4.0 中获得 WEBrick 完全多线程,只需将其添加到config/initializers/multithreaded_webrick.rb

# Remove Rack::Lock so WEBrick can be fully multi-threaded.
require 'rails/commands/server'

class Rails::Server
  def middleware
    middlewares = []
    middlewares << [Rails::Rack::Debugger] if options[:debugger]
    middlewares << [::Rack::ContentLength]

    Hash.new middlewares
  end
end

rails/commands/server.rb我们摆脱的违规代码是:

# FIXME: add Rack::Lock in the case people are using webrick.
# This is to remain backwards compatible for those who are
# running webrick in production. We should consider removing this
# in development.
if server.name == 'Rack::Handler::WEBrick'
  middlewares << [::Rack::Lock]
end

Rails 4.2 不需要它。它是开箱即用的并发。

于 2014-01-06T00:12:09.347 回答
5

你在使用 WEBrick服务器吗?那一定是因为您的服务器是单线程服务器,并且能够一次完成一个请求(因为单个工作线程)。现在,如果有多个请求,它会运行请求的操作部分,并在运行视图渲染器之前检查是否有任何待处理的请求。现在如果有 10 个请求排队,它会在实际渲染视图之前先完成所有请求。当所有这些请求都完成后,视图现在将按顺序呈现。

如果您想要多线程环境,您可以切换到Passenger 或Unicorn 服务器。

希望这是有道理的。

于 2012-12-25T05:08:52.010 回答
0

在您的环境设置 config/environments/development.rb 下(或在 config/application.rb 中)

添加这一行:

  #Enable threaded mode
  config.threadsafe!
于 2016-08-03T18:41:04.170 回答