我正在使用 puma 和 nxinx,据我所知,即使我以默认的 16 个线程或更多线程启动它,它也只使用一个线程。我已经设置了一个全新的 rails 应用程序,然后按照此处描述的设置进行操作:
http://blog.wiemann.name/rails-server
这给出了以下示例 nginx 配置:
upstream benchmarkapp.com {server unix:/tmp/benchmark_app.sock fail_timeout=0;}
server {
server_name benchmarkapp.com;
root /home/tristan/benchmark_app/public;
try_files $uri/index.html $uri @benchmarkapp.com;
location @benchmarkapp.com {
proxy_redirect off;
proxy_pass http://benchmarkapp.com;
}
}
然后创建一个简单的控制器操作,它只休眠 3 秒钟,然后呈现“hello”:
class WelcomeController < ApplicationController
def index
sleep(2)
render :text => "hello"
end
end
然后我开始使用 puma:puma -t 16 -b unix:///tmp/benchmark_app.sock -S /tmp/benchmark_app.state
运行后,我使用 siege 测试了 10 个并发用户,结果如下
% siege -c 10 -t 60s http://benchmarkapp.com
** SIEGE 2.70
** Preparing 10 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200 2.04 secs: 25 bytes ==> /
HTTP/1.1 200 4.05 secs: 25 bytes ==> /
HTTP/1.1 200 6.06 secs: 25 bytes ==> /
HTTP/1.1 200 8.08 secs: 25 bytes ==> /
HTTP/1.1 200 10.09 secs: 25 bytes ==> /
如果应用程序以单线程运行,这正是我期望看到的。以前两个请求为例。它们大致同时到达。第一个请求需要两秒钟,到目前为止一切顺利。但第二个、第三个……直到第十个请求都必须为它之前的每个请求额外等待 2 秒钟。事实上,如果我只用 1 个线程重新启动 puma,我会得到确切地这个结果。
我在这里做错了什么?我怎样才能让服务器真正使用 puma 生成的所有线程?如果一切正常,我希望看到:
% siege -c 10 -t 60s http://benchmarkapp.com
** SIEGE 2.70
** Preparing 10 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200 2.04 secs: 25 bytes ==> /
HTTP/1.1 200 2.05 secs: 25 bytes ==> /
HTTP/1.1 200 2.03 secs: 25 bytes ==> /
HTTP/1.1 200 2.01 secs: 25 bytes ==> /
HTTP/1.1 200 2.06 secs: 25 bytes ==> /
我怎样才能实现这一点?
答案1
在网上进行了大量的研究并试图弄清楚如何让 Puma 真正使用线程之后,我终于明白了。
您可以config.allow_concurrency = true
在应用程序配置中使用。这将删除使用Rack::Lock
GIL 负责 ruby 中线程安全的中间件(它确保一次只运行 1 个线程)。
要验证您的配置,请使用rake middleware
并确保您不会use Rack::Lock
在列表中看到。