在heroku dyno的上下文中,puma工人和puma线程有什么区别?我所知道的(如有错误请纠正):
但是在puma中有线程和工作者......工作者不就是puma进程中的线程吗?我可以在Heroku中使用更多的工作线程来增加Web并发性吗?
to94eoyn1#
正如另一个答案所说,这个Heroku article非常好地解释了某些配置项。然而,如果您需要在Heroku或任何地方调优应用程序,那么了解工作原理是值得的。我认为你说的“worker是puma进程内部的线程”几乎是正确的,我相信worker是从puma派生出来的操作系统级进程,它可以在内部使用线程。据我所知,puma将分叉它的操作系统进程,无论你通过workers配置设置多少次来响应http请求,这给了你处理多个请求的并行性,但这通常会占用更多的内存,因为它将为每个工作者“复制”你的应用程序代码。每个puma工作线程将根据threads配置在其操作系统进程中使用多个线程。这些线程通过允许puma进程响应多个请求来增加并发性,这样,如果一个线程被阻塞,即处理一个请求,它可以用另一个线程处理一个新的请求。如上所述,这需要您的整个应用程序是线程安全的,以便,例如,来自一个请求的任何全局配置不会“泄漏”到另一个请求中。您可以调整puma,使工作线程的数量足以满足CPU和可用内存的数量,然后根据您希望运行应用程序的主机达到的饱和程度以及应用程序的行为方式来调整线程-更多并不总是等于更快/更多的请求吞吐量。
workers
threads
js4nwp542#
这是一个很大的领域,我不是Maven,但是...Puma可以产生许多工作者,每个工作者可以使用许多线程来处理请求。据我所知,独角兽没有线程,它只有工人模型。如果你使用线程,你需要确保你的代码是线程安全的,这意味着Rails,你所依赖的任何gem,以及你自己的代码。为了获得最佳性能,您可能还需要查看JRuby或Rubinius,它们具有适当的线程支持。MRI受其GIL的限制。有一个good article on Heroku解释了Puma如何使用工作者和线程。您可能应该阅读它并忽略我:)
ifmq2ha23#
我只想强调这里引用的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个Workers,每个Workers有5个线程,那么2 * 5 = 10,因此您的数据库必须配置为接受10个并发连接。
z2acfund4#
试着从一个人的Angular 来回答这个问题,这个人是在线程理解之旅的开始:
dwthyt8l5#
工人:-
5条答案
按热度按时间to94eoyn1#
正如另一个答案所说,这个Heroku article非常好地解释了某些配置项。
然而,如果您需要在Heroku或任何地方调优应用程序,那么了解工作原理是值得的。
我认为你说的“worker是puma进程内部的线程”几乎是正确的,我相信worker是从puma派生出来的操作系统级进程,它可以在内部使用线程。
据我所知,puma将分叉它的操作系统进程,无论你通过
workers
配置设置多少次来响应http请求,这给了你处理多个请求的并行性,但这通常会占用更多的内存,因为它将为每个工作者“复制”你的应用程序代码。每个puma工作线程将根据
threads
配置在其操作系统进程中使用多个线程。这些线程通过允许puma进程响应多个请求来增加并发性,这样,如果一个线程被阻塞,即处理一个请求,它可以用另一个线程处理一个新的请求。如上所述,这需要您的整个应用程序是线程安全的,以便,例如,来自一个请求的任何全局配置不会“泄漏”到另一个请求中。您可以调整puma,使工作线程的数量足以满足CPU和可用内存的数量,然后根据您希望运行应用程序的主机达到的饱和程度以及应用程序的行为方式来调整线程-更多并不总是等于更快/更多的请求吞吐量。
js4nwp542#
这是一个很大的领域,我不是Maven,但是...
Puma可以产生许多工作者,每个工作者可以使用许多线程来处理请求。
据我所知,独角兽没有线程,它只有工人模型。
如果你使用线程,你需要确保你的代码是线程安全的,这意味着Rails,你所依赖的任何gem,以及你自己的代码。
为了获得最佳性能,您可能还需要查看JRuby或Rubinius,它们具有适当的线程支持。MRI受其GIL的限制。
有一个good article on Heroku解释了Puma如何使用工作者和线程。您可能应该阅读它并忽略我:)
ifmq2ha23#
我只想强调这里引用的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个Workers,每个Workers有5个线程,那么2 * 5 = 10,因此您的数据库必须配置为接受10个并发连接。
z2acfund4#
试着从一个人的Angular 来回答这个问题,这个人是在线程理解之旅的开始:
1.一个工作线程可以被配置为多个线程,重要的是要知道这些线程中的每一个都将与这个特定工作线程的其他线程共享相同的RAM和ENV变量的状态。
1.一个工作线程一次可以处理一个线程,因此当当前线程在执行某些处理时卡住时,该工作线程将开始处理新线程。
1.给定变量的状态在所有线程之间共享的事实,这可能导致第一线程已经改变了第二线程将需要处于初始状态的可变数据结构。
让你的代码线程安全通常是很复杂的。除了在其他答案中提出的解决方案外,我还要说,研究互斥体并了解你的数据库处理线程的方式是一个好主意。为此,我推荐这个Postgresql SO答案。
dwthyt8l5#
工人:-
螺纹:-