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

Nic*_*nto 50 multithreading heroku puma ruby-on-rails-4

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

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

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

  • 在独角兽中,我知道我可以在一个进程中有几个unicorn worker来添加并发性.

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

我可以在Heroku中使用更多的worker/threads来添加web并发吗?

小智 41

正如其他答案所述,这篇Heroku文章对某些配置项的解释非常好.

但是,如果您需要在Heroku或任何地方调整您的应用程序,那么知道如何工作是值得的.

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

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

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

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


jor*_*ver 15

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

Puma可以生成许多worker,每个worker可以使用很多线程来处理请求.

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

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

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

Heroku上有一篇很好的文章解释了Puma如何使用工作者和线程.你可能应该阅读并忽略我:)


Don*_*ato 5

我只想强调一下此处引用的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个工作线程,每个工作线程有5个线程,则2 * 5 = 10,因此必须将数据库配置为接受10个并发连接。