测试准备:
在一个操作中执行sleep 10
测试: 在浏览器中打开两个标签页以访问该操作
结果: 当第二个请求正在运行时,第一个请求已完成并开始渲染视图,但是视图仍然为空白。 在第二个请求也完成后,两个请求同时完成了视图的渲染。
结论: Rails只是一个单一的实例。一个请求只能在前面的请求完成后进入该操作。但如何解释响应部分呢?为什么多个请求可以同时完成视图的渲染呢?
测试准备:
在一个操作中执行sleep 10
测试: 在浏览器中打开两个标签页以访问该操作
结果: 当第二个请求正在运行时,第一个请求已完成并开始渲染视图,但是视图仍然为空白。 在第二个请求也完成后,两个请求同时完成了视图的渲染。
结论: Rails只是一个单一的实例。一个请求只能在前面的请求完成后进入该操作。但如何解释响应部分呢?为什么多个请求可以同时完成视图的渲染呢?
WEBrick是多线程的,但Rails开发人员硬编码了一个互斥锁,因此它只能一次处理一个请求。您可以猴子补丁Rails:: Server,然后您就可以自由运行多线程的WEBrick。
请注意,仅当配置config.cache_classes = true和config.eager_load = true时,WEBrick才会是多线程的,这通常是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上不需要它,因为它是开箱即用的并发。
config.threadsafe!
不会自动使 WEBrick 多线程化。有关详细信息,请参阅我的答案。 - Nowaker #Enable threaded mode
config.threadsafe!
RAILS_ENV=production
环境下默认支持并发。 - Nowakerconfig.middleware.delete 'Rack::Lock'
。 - Benj