Puma中的Workers和Threads有什么区别?

时间:2014-06-18 08:32:01

标签: multithreading heroku ruby-on-rails-4 puma

在heroku dyno的背景下,美洲狮工人和美洲狮线程有什么区别?

我所知道的(如果我错了,请纠正我):

  • 精简不是并发的,因此网络流程一次只能执行一个请求

  • 在独角兽中,我知道我可以在一个进程中有几个独角兽工作者来增加并发性。

但是在美洲狮有线程和工人..在美洲狮过程中,工人不是一个线程吗?

我可以使用更多的工作人员/线程在Heroku中添加Web并发吗?

3 个答案:

答案 0 :(得分:35)

正如另一个答案所述,对于某些配置项的解释,这个Heroku article非常好。

但是,如果您需要在Heroku或任何地方调整您的应用程序,那么了解事情的运作方式是值得的。

当你说"工人是美洲狮过程中的一个线程时,我认为你几乎是正确的,我认为一个工作者是一个从puma分叉的操作系统级进程,然后可以在内部使用线程。 / p>

据我所知 - puma会分叉其操作系统进程,但很多时候你通过workers配置来响应http请求。这使您在处理多个请求方面具有并行性,但这通常会占用更多内存,因为它会复制'每个工人的应用程序代码。

然后,每个puma worker将在其OS过程中使用多个线程,具体取决于threads配置。这些通过允许puma进程自己响应多个请求来添加并发性,这样如果一个线程被阻塞,即处理请求,它就可以处理另一个线程的新请求。如上所述,这要求您的整个应用程序都是线程安全的,以便例如来自一个请求的任何全局配置都不会泄漏'到另一个。

你会调整puma,以便工作人员的数量足以满足可用CPU和内存的数量,然后根据运行应用程序的主机的饱和程度以及应用程序的行为来调整线程 - 更多的是并不总是等于更快/更多的请求吞吐量。

答案 1 :(得分:14)

这是一个很大的领域,我不是专家,但是......

Puma可以产生许多工作者,每个工作者可以使用许多线程来处理请求。

据我所知,Unicorn没有线程,它只有工人模型。

如果你使用线程,你需要确保你的代码是线程安全的。这意味着Rails,您依赖的任何宝石,以及您自己的代码。

为了获得最佳性能,您可能还需要查看具有正确线程支持的JRubyRubinius。 MRI受其GIL限制。

有一个good article on Heroku解释了Puma如何使用工作者和线程。你可能应该阅读并忽略我:)

答案 2 :(得分:0)

我只想强调一下此处引用的Heroku / Puma文章中最重要的一行:

  

Rails维护自己的数据库连接池,并带有一个新的池   为每个工作进程创建的。工作线程中的线程将运行   在同一个池中。

声明每个工人将拥有自己的游泳池。但是:

  

工作线程中的线程将在同一池上运行。

这非常重要。如果Puma Worker每个工人使用5个线程,则必须将database.yml配置为5个连接池,因为每个线程都可能建立数据库连接。

由于每个Worker都由系统fork()产生,因此新Worker将拥有自己的5个线程集,因此对于创建的新Rails实例,database.yml仍将设置为连接5人的池。

现在,database.yml连接池和实际的数据库池是两回事。与数据库的TOTAL连接将需要使用Heroku文档提到的特定公式:

  

确定每个应用程序所需连接数的一个好公式是将RAILS_MAX_THREADS乘以WEB_CONCURRENCY。

这意味着,如果您正在使用2个Worker,每个Worker具有5个线程,则2 * 5 = 10,因此必须将数据库配置为接受10个并发连接。