Sinatra 是多线程的吗?我在其他地方读到“sinatra 默认情况下是多线程的”,这意味着什么?
考虑这个例子
get "/multithread" do
t1 = Thread.new{
puts "sleeping for 10 sec"
sleep 10
# Actually make a call to Third party API using HTTP NET or whatever.
}
t1.join
"multi thread"
end
get "/dummy" do
"dummy"
end
如果我随后在另一个选项卡或浏览器中访问“/multithread”和“/dummy”,则在“/multithread”请求完成之前无法提供任何服务(在本例中为 10 秒)。如果活动冻结,应用程序将变得无响应。
我们如何解决这个问题而不产生应用程序的另一个实例?
tl;dr Sinatra 与 Threads 配合得很好,但您可能必须使用不同的 Web 服务器。
Sinatra 本身不强加任何并发模型,它甚至不处理并发。这是由机架处理程序(Web 服务器)完成的,例如 Thin、WEBrick 或 Passenger。 Sinatra 本身是线程安全的,这意味着如果您的 Rack 处理程序使用多个线程来服务器请求,它就可以正常工作。然而,由于 Ruby 1.8 仅支持绿色线程,而 Ruby 1.9 具有全局 VM 锁,因此线程并没有广泛用于并发,因为在这两个版本上,线程都不会真正并行运行。然而,JRuby 或即将推出的 Rubinius 2.0(都是替代的 Ruby 实现)将是这样。
大多数使用线程的现有机架处理程序将使用线程池来重用线程,而不是为每个传入请求实际创建一个线程,因为线程创建不是免费的,尤其是。在 1.9 中,线程以 1:1 的方式映射到本机线程。绿色线程的开销要少得多,这就是为什么 Fiber(基本上是协作调度的绿色线程,如上面提到的 sinatra-synchrony 使用的)最近变得如此流行的原因。您应该注意,任何网络通信都必须经过 EventMachine,因此您不能使用mysql
例如,gem 可以与您的数据库对话。
光纤对于网络密集处理来说可以很好地扩展,但对于繁重的计算来说却会严重失败。如果您使用纤程,那么您不太可能遇到竞争条件,这是并发的常见陷阱,因为它们仅在明确定义的点上进行上下文切换(使用同步,每当您等待 IO 时)。还有第三种常见的并发模型:进程。您可以使用预分叉服务器或自己启动多个进程。虽然乍一看这似乎是一个坏主意,但它有一些优点:在正常的 Ruby 实现中,这是同时使用所有 CPU 的唯一方法。并且您避免共享状态,因此根据定义没有竞争条件。此外,多进程应用程序可以轻松地在多台机器上扩展。请记住,您可以将多个进程与其他并发模型(事件、协作、抢占)结合起来。
选择主要取决于您使用的服务器和中间件:
- 多进程、非预分叉:Mongrel、Thin、WEBrick、Zbatery
- 多进程、预分叉:Unicorn、Rainbows、Passenger
- Evented(适合 sinatra 同步):Thin、Rainbows、Zbatery
- 线程:Net::HTTP::Server、Threaded Mongrel、Puma、Rainbows、Zbatery、Thin[1]、Phusion 客运企业 >= 4 https://www.phusionpassenger.com/
[1] 自 Sinatra 1.3.0 起,如果 Thin 由 Sinatra 启动(即使用ruby app.rb
,但不与thin
命令,也不与rackup
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)