RAILS_MAX_THREAD是Puma在构建期间设置和缩放的东西,还是我应该设置它?

Mic*_*ael 5 multithreading heroku puma ruby-on-rails-5 actioncable

我知道Rails 5附带了Puma(我们正在使用)并将查找RAILS_MAX_THREADS作为环境变量或默认为5个线程,但我接收到默认值的超时错误.我查看了我的数据库,发现它的最大连接数是几千.

它可能很愚蠢,但这是Puma会根据其设置自动设置和缩放的内容,还是我需要在环境变量中明确设置它?如果需要手动设置,RAILS_MAX_THREADS的价值是多少?

我发现以下内容很有帮助,但我还没有完全掌握可扩展性部分:

https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server https://devcenter.heroku.com/articles/concurrency-and-database-connections

Nic*_*nov 15

Puma实际上有两个参数,线程数和工人数.如果我们略微更改默认值puma.rb,它将如下所示:

# WORKERS_NUM is not a default env variable name
workers Integer(ENV['WORKERS_NUM'] || 1)
max_threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 1)
min_threads_count = max_threads_count
threads min_threads_count, max_threads_count
Run Code Online (Sandbox Code Playgroud)

工作者数量是Puma为您生成的单独进程的数量.通常,最好将其设置为等于服务器上的处理器核心数.您可以生成更多的请求以允许同时处理更多请求,但是工作人员会创建额外的内存开销 - 每个工作者都会旋转rails应用程序的副本,因此通常,您将使用线程来实现更高的吞吐量.

RAILS_MAX_THREADS是一种设置每个工作人员将在引擎盖下使用的线程数的方法.在上面的例子中,min_threads_count它等于max_threads_count,所以线程的数量是不变的.如果你将它们设置为不同,它将从最小值扩展到最大值,但我没有在野外看到它.

限制线程数有几个原因 - 您的解释器和响应时间:

  1. 如果您使用MRI,您的线程受GIL限制,因此它们不会并行运行.MRI通过上下文切换模仿并行执行.大量线程将允许更多的同时连接,但由于GIL,平均响应时间将增加.
  2. 平台限制:即heroku具有线程数限制https://devcenter.heroku.com/articles/dynos#process-thread-limits,linux仅限制进程数Linux中每个进程的最大线程数?.
  3. 当代码不是线程安全的时,使用多个线程可能会导致不可预测的问题.这实际上是我的情况,所以我没有尝试过多少线程.

还有一种观点认为,缓慢的IO会阻止ruby进程并且不允许上下文切换(即调用外部服务,或者动态生成大型文件),但事实证明并非如此.http://yehudakatz.com/ 2010/08/14/threads-in-ruby-enough-already-.但是,优化您的架构以尽可能多地在后台完成工作总是一个好主意.

这个答案将帮助您找到线程数与给定硬件的工作者数量的完美组合.

这显示了如何进行基准测试以找到确切的数字.

总结: WORKERS_NUM乘以RAILS_MAX_THREADS给出了puma可以处理的最大同时连接数.如果数字太低,您的用户将在加载峰值期间看到超时.为了在使用MRI时获得最佳性能,您需要设置WORKERS_NUM核心数,并RAILS_MAX_THREADS根据性能测试期间的平均响应时间找到最佳.

  • 我认为每个工作者都有一个新的连接池,所以如果你有2个工人,每个工作者有5个线程,那么你应该只需要5个连接池(而不是10个).如果我错了,请纠正我? (2认同)