我已经阅读了大量涉及 Ruby 和 Rails 不同版本中线程安全和性能的内容,我认为现在我对这些问题有了比较好的理解。
但是,在讨论如何实际部署异步 Rails 应用程序时,似乎缺少一些奇怪的东西。在谈论应用程序中的线程和同步性时,人们想要优化两件事情:
1. 最小化 RAM 使用率,利用所有 CPU 核心。
2. 能够在之前的请求等待 IO 时服务新请求。
第一点是人们对 JRuby 的(正确)兴奋之处。对于这个问题,我只尝试优化第二点。
假设这是我应用程序中唯一的控制器:
但是,在讨论如何实际部署异步 Rails 应用程序时,似乎缺少一些奇怪的东西。在谈论应用程序中的线程和同步性时,人们想要优化两件事情:
1. 最小化 RAM 使用率,利用所有 CPU 核心。
2. 能够在之前的请求等待 IO 时服务新请求。
第一点是人们对 JRuby 的(正确)兴奋之处。对于这个问题,我只尝试优化第二点。
假设这是我应用程序中唯一的控制器:
class TheController < ActionController::Base
def fast
render :text => "hello"
end
def slow
render :text => User.count.to_s
end
end
fast
没有IO,可以每秒服务数百或数千个请求,而slow
必须通过网络发送请求,等待工作完成,然后通过网络接收答案,因此比fast
慢得多。
因此,理想的部署将允许在等待IO的情况下满足对fast
的数百个请求。
似乎在网络讨论中缺少的是哪个层面的堆栈负责启用此并发。thin有一个--threaded
标志,它将“以线程方式调用Rack应用程序[实验性]”--这是否为每个传入请求启动一个新线程?在线程中拆分rack应用程序实例,这些实例会持续存在并等待传入请求吗?
thin是唯一的方法还是还有其他方法?对于优化点2,Ruby运行时是否重要?