Ruby on Rails不支持多线程的方式是什么?

28

什么是多线程

"多线程"在Web应用程序中的理解有两个方面:

  1. 每次Web/App服务器接收到请求时,它可以为新请求分配一个线程,从而可以并发运行多个请求。
  2. 应用程序运行时和语言允许在单个请求内使用多个线程(在ASP.NET中通过“Async”方法和关键字进行,例如)。

这样,IIS7 + ASP.NET可以完成1和2两点。

我对RoR感到困惑

我读了这两篇文章,但它们让我感到困惑:

第一个问题

我认为我理解RoR不太适合上述2中的点即:在同一请求中使用多个线程,我的理解是否正确?

第二个问题

为了非常清楚,RoR应用程序/Web服务器也可以做到上述第1点(即多个请求可以并发运行),这在RoR中并不总是成立对吗?


1
嘿,BoltClock,你能留下至少一个ASP.NET标签吗?通常开发人员不是从头开始学习,而是迁移,我认为拥有ASP.NET标签对其他C#开发人员很有帮助...例如,我更喜欢“面向C#开发人员的Objective C”而不是“没有任何上下文的学习Objective C!”;-) - andy
3个回答

37

问题1: 如果需要,您可以在一个请求中生成更多的Ruby线程,尽管这似乎超出了Rails的典型用例。对于某些长时间运行的IO或外部操作,它具有一定的使用价值。

问题2: 总体而言,不仅限于Rails,Ruby并发的限制因素是 全局解释器锁。Ruby的这个特性防止每个进程中同时执行超过1个Ruby线程。当有非Ruby代码正在执行(例如等待磁盘IO或SQL响应)时,锁将被释放。你可以通过使用与默认值不同的Ruby实现(如JRuby)来解决这个问题,但并非所有实现都支持。

Phusion Passenger 使用基于进程的并发处理少量请求,所以严格来说并不是 "多线程",但它仍然是并发的。

这篇来自2011年Ruby Midwest的演讲 对于启动多线程的Ruby on Rails有一些好的想法。


3
+1 很棒的答案!谢谢 kjw。天啊...所以,就第二点而言,为什么RoR如此受欢迎?这似乎是一个关于规模的巨大问题,是吗? - andy
2
有些人认为这是一个问题,并且多年来一直在讨论这个问题。Rails的优点是开发时间更快,缺点是它的扩展性不如其他技术。需要注意的是,如果你增加硬件,它仍然可以扩展,所以并不存在扩展的“天花板”,但是它的扩展性不如Java应用程序等其他技术高效。 - kjw0188
1
@kjw0188 同意。我最终用 Go 替换了 Rails 代码片段,Go 的性能更好。即使是对于微不足道的情况,我在 Rails 和多线程方面也从未有过什么好运气。 - alediaferia

3
由于这是关于“从ASP.NET到RoR”的内容,还有一个小但重要的细节需要记住:在*nix环境中,通过多进程而不是多线程实现服务应用程序的并发是很常见的。这是一种古老的架构,与在*nix系统上使用forkCopy-on-Write相对便宜的多处理器成本有关。每个进程在单个线程中一次服务一个请求,主进程控制生成和杀死工作子进程。不同的子进程同时提供多个请求。
现代服务应用程序(例如Apache)具有多进程、多线程甚至组合模式(其中服务分叉多个进程,每个进程运行几个线程)。
在那些考虑了可移植性的应用程序中(例如Apache,MySQL等),习惯上在*nix系统上以多进程或组合模式运行,在Windows服务器上以多线程模式运行。
然而,不可否认的是Rails在Windows方面有些欠缺。并不是说你不能在Windows上运行它,只是没有投入太多精力来确保它在Windows服务器上的生产使用运行良好和顺畅。这不是RoR社区中常见的生产平台。
因此,尽管Rails自2.2版本以来就是线程安全的,但在Windows服务器上尚没有一个好的多线程服务器。通过在*nix服务器上使用多进程/单线程并发模型来运行,可以获得最佳结果。

2
作为一个框架,Rails是线程安全的。所以,答案是肯定的!
你发布的第二个链接列出了许多不适合多线程的Rails服务器。他后来提到nginx是最好的选择(它绝对是最流行的和高度推荐的)。但他没有提到是什么让他得出这个结论。 Ruby 1.9.3最近推出,并且具有一些新的线程好处,这些好处之前不存在。
多线程的使用通常取决于用例。个人而言,我在一年前尝试过它,并且它可以工作,但我没有在任何生产代码中使用它,因为我没有遇到使用多线程比将长时间运行的任务推送到后台作业更有意义的用例。
我很想进一步探索这个问题。因此,如果您可以描述您要实现的内容,那么也许我们可以进行POC。

+1 感谢您的回答,Vibhor!但是,您能否再详细解释一下您的回答?我仍然不确定您回答的是什么。您说答案是“是”,但问题是什么导致了这个“是”的回答?;-) 如果您能再澄清一下,那就太棒了。谢谢。 - andy
我一直在关注这个话题的讨论,结论是,在Rails上进行多线程编程的最佳选择是使用支持本地线程的jRuby。但是,您可能会受到可用于您的Ruby gem(库)选择的限制。 - Vibhor Mahajan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接