Sinatra是多线程的吗?

时间:2011-06-08 12:40:29

标签: ruby sinatra

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”,则无法提供任何内容(在这种情况下为10秒),直到“/ multithread”请求完成。如果活动冻结应用程序变得没有响应。

我们如何在不产生应用程序的另一个实例的情况下解决这个问题?

5 个答案:

答案 0 :(得分:91)

tl; Sinatra博士与Threads合作得很好,但你可能不得不使用不同的网络服务器。

Sinatra本身并没有强加任何并发模型,它甚至不处理并发。这是由Rack处理程序(Web服务器)完成的,如Thin,WEBrick或Passenger。 Sinatra本身是线程安全的,这意味着如果您的Rack处理程序使用多个线程来处理服务器请求,它就可以正常运行。但是,由于Ruby 1.8仅支持绿色线程,而Ruby 1.9具有全局VM锁定,因此线程并不广泛用于并发,因为在这两个版本中,线程不会真正并行运行。但是,这将是JRuby或即将推出的Rubinius 2.0(两种替代Ruby实现)的意愿。

使用线程的大多数现有Rack处理程序将使用线程池来重用线程而不是为每个传入请求实际创建线程,因为线程创建不是免费的,尤其是。在1.9上,线程将1:1映射到本机线程。绿色螺纹的开销要小得多,这就是为什么纤维,基本上是合作安排的绿色螺纹,如上面提到的sinatra-synchrony所使用的,最近变得如此受欢迎。您应该知道任何网络通信都必须通过EventMachine,因此您不能使用mysql gem来与您的数据库通信。

纤维可以很好地适应网络密集处理,但是对于繁重的计算而言却很惨。如果你使用光纤,你不太可能遇到竞争条件,这是常见的并发陷阱,因为它们只在明确定义的点上进行上下文切换(在你等待IO的情况下使用同步)。还有第三种常见的并发模型:进程。您可以使用preforking服务器或自己启动多个进程。虽然这看起来不是一个坏主意,但它有一些优点:在正常的Ruby实现中,这是同时使用所有CPU的唯一方法。并且你避免共享状态,因此根据定义没有竞争条件。此外,多进程应用程序可以轻松扩展到多台计算机请记住,您可以将多个流程与其他并发模型(事件,协作,抢占)结合使用。

选择主要取决于您使用的服务器和中间件:

  • 多进程,非预先执行:Mongrel,Thin,WEBrick,Zbatery
  • 多进程,预制:独角兽,彩虹,乘客
  • Evented(适合sinatra-synchrony):Thin,Rainbows,Zbatery
  • 线程:Net :: HTTP :: Server,Threaded Mongrel,Puma,Rainbows,Zbatery,Thin [1],Phusion Passenger Enterprise >= 4

[1]自Sinatra 1.3.0起,Thin将以线程模式启动,如果它由Sinatra启动(即使用ruby app.rb,但不是thin命令启动,也不启动{{ 1}})。

答案 1 :(得分:6)

在谷歌上搜索时,发现了这个宝石:

sinatra-synchrony

这对你有帮助,因为它会触动你的问题。

还有一个基准测试,他们做的几乎和你想要的一样(外部电话)。

结论:EventMachine就是答案!

答案 2 :(得分:4)

我想我可能会为遇到此事的人详细说明。 Sinatra包含了这一小块代码:

   server.threaded = settings.threaded if server.respond_to? :threaded=    

Sinatra将检测您为网络服务器安装的gem(也就是瘦,美洲狮等等),如果它响应“线程”,则会将其设置为线程(如果请求)。整齐。

答案 3 :(得分:1)

对代码进行一些更改后,我可以在mizuno上运行padrino / sinatra应用程序 。最初我试图在jRuby上运行Padrino应用程序,但它太不稳定了,我没有调查为什么。在jRuby上运行时,我遇到了JVM崩溃问题。我还浏览了this文章,这让我想到为什么即使选择Ruby也可以轻松实现部署。

是否有关于在ruby中部署应用程序的讨论?或者我可以生成一个新线程:)

答案 4 :(得分:1)

我最近一直在接触JRuby,我非常惊讶从MRI切换到JRuby是多么简单。它几乎涉及交换一些宝石(在大多数情况下)。

您应该看一下JRuby和Trinidad(App Server)的组合。 Torquebox似乎也是一个有趣的一体化解决方案,它不仅仅是一个应用服务器。

如果你想拥有一个支持线程的应用服务器,并且你熟悉Mongrel,Thin,Unicorn等,那么Trinidad可能是最容易迁移到的,因为从用户的角度看它几乎是相同的。到目前为止爱它!