准备测试:
sleep 10
在行动中
测试: 在浏览器中打开两个标签页访问动作
结果: 当第二个请求运行时,第一个请求完成并开始渲染视图,但视图仍然是空白的。在第二个请求也完成后,这两个请求同时完成了视图的渲染。
结论: Rails 只是一个实例。一个请求只有在前一个请求完成后才能进入动作。但是如何解释响应部分?为什么多个请求同时完成视图的渲染?
准备测试:
sleep 10
在行动中
测试: 在浏览器中打开两个标签页访问动作
结果: 当第二个请求运行时,第一个请求完成并开始渲染视图,但视图仍然是空白的。在第二个请求也完成后,这两个请求同时完成了视图的渲染。
结论: Rails 只是一个实例。一个请求只有在前一个请求完成后才能进入动作。但是如何解释响应部分?为什么多个请求同时完成视图的渲染?
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 不需要它。它是开箱即用的并发。
你在使用 WEBrick
服务器吗?那一定是因为您的服务器是单线程服务器,并且能够一次完成一个请求(因为单个工作线程)。现在,如果有多个请求,它会运行请求的操作部分,并在运行视图渲染器之前检查是否有任何待处理的请求。现在如果有 10 个请求排队,它会在实际渲染视图之前先完成所有请求。当所有这些请求都完成后,视图现在将按顺序呈现。
如果您想要多线程环境,您可以切换到Passenger 或Unicorn 服务器。
希望这是有道理的。
在您的环境设置 config/environments/development.rb 下(或在 config/application.rb 中)
添加这一行:
#Enable threaded mode
config.threadsafe!