在heroku dyno的背景下,美洲狮工人和美洲狮线程有什么区别?
我所知道的(如果我错了,请纠正我):
但在美洲狮有线程和工人..在美洲狮过程中,工人不是一个线程吗?
我可以在Heroku中使用更多的worker / threads来添加web并发吗?
正如另一个答案所述,这个Heroku article非常适合解释某些配置项。
但是,如果您需要在Heroku或任何地方调整您的应用程序,那么知道如何工作是值得的。
当你说“一个工人是美洲狮过程中的一个线程”时,我认为你几乎是正确的,我相信一个工人是一个从puma分叉的操作系统级进程,然后可以在内部使用线程。
据我了解 - puma将分叉其操作系统进程,但是很多时候你通过workers
配置来响应http请求。这使您在处理多个请求方面具有并行性,但这通常会占用更多内存,因为它将“复制”每个工作程序的应用程序代码。
然后,每个puma worker将在其OS过程中使用多个线程,具体取决于threads
配置。这些通过允许puma进程自己响应多个请求来添加并发性,这样如果一个线程被阻塞,即处理请求,它就可以处理另一个线程的新请求。如上所述,这要求您的整个应用程序都是线程安全的,例如,来自一个请求的任何全局配置都不会“泄漏”到另一个请求中。
您可以调整puma,以便工作人员的数量足以满足可用CPU和内存的数量,然后根据运行应用程序的主机的饱和程度以及应用程序的行为方式调整线程 - 更多并不总是等于更快/更多请求吞吐量。
这是一个很大的领域,我不是专家,但是......
Puma可以生成许多worker,每个worker可以使用很多线程来处理请求。
据我所知,Unicorn没有线程,它只有工人模型。
如果您使用线程,则需要确保代码是线程安全的。这意味着Rails,您依赖的任何宝石,以及您自己的代码。
为了获得最佳性能,您可能还需要查看具有适当线程支持的JRuby或Rubinius。 MRI受其GIL限制。
有一个good article on Heroku解释了Puma如何使用工人和线程。你可能应该阅读并忽略我:)
我只想强调这里引用的Heroku / Puma文章中最重要的一行:
Rails维护自己的数据库连接池,并为每个工作进程创建一个新池。工作线程中的线程将在同一个池中运行。
它声明每个工人都有自己的池。然而:
工作线程中的线程将在同一个池中运行。
这一点非常重要。如果Puma Worker每个worker使用5个线程,则必须将database.yml配置为5的连接池,因为每个线程都可能建立数据库连接。
由于每个Worker都是由系统fork()生成的,因此新worker将拥有自己的5个线程集,因此对于创建的新Rails实例,database.yml仍将设置为5的连接池。
现在,database.yml连接池和您的实际数据库池是两回事。与数据库的TOTAL连接需要使用Heroku文档提到的特定公式:
确定每个应用程序所需连接数的一个好公式是将RAILS_MAX_THREADS乘以WEB_CONCURRENCY。
这意味着如果您使用2个Worker,每个都有5个线程,然后2 * 5 = 10,那么您的数据库必须配置为接受10个并发连接。