multithreading - RAILS_MAX_THREADS 是 Puma 会在构建时设置和缩放的东西,还是我应该设置它?

标签 multithreading heroku ruby-on-rails-5 puma 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

最佳答案

Puma其实有两个参数,线程数和worker数。如果我们稍微改变默认 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
worker 数量是 Puma 为您生成的独立进程的数量。通常,最好将其设置为与服务器上的处理器内核数相等。您可以生成更多的它们以允许同时处理更多的请求,但工作人员会产生额外的内存开销——每个工作人员都会启动一份 Rails 应用程序的副本,因此通常,您会使用线程来实现更高的吞吐量。RAILS_MAX_THREADS是一种设置每个工作人员将在后台使用的线程数的方法。在上面的例子中,min_threads_count等于 max_threads_count ,所以线程数是恒定的。如果您将它们设置为不同,它将从最小值缩放到最大值,但我还没有在野外看到它。
限制线程数的原因有很多——你的解释器和响应时间:
  • 如果您使用 MRI,您的线程会受到 GIL 的限制,因此它们不会并行运行。 MRI 通过上下文切换模拟并行执行。大量线程将允许更多的同时连接,但由于 GIL,平均响应时间会增加。
  • 平台限制:即 heroku 有线程数限制 https://devcenter.heroku.com/articles/dynos#process-thread-limits , linux 只限制进程数Maximum number of threads per process in Linux? .
  • 当代码不是线程安全的时,使用多个线程可能会导致不可预知的问题。这实际上是我的情况,所以我没有对线程数进行太多实验。

  • 还有一个论点认为慢速 IO 会阻塞 ruby​​ 进程并且不允许上下文切换(即调用外部服务,或动态生成大文件),但事实证明并非如此 http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/ .但是优化您的架构以在后台完成尽可能多的工作始终是一个好主意。
    This answer将帮助您找出线程数量与给定硬件的 worker 数量的完美组合。
    This shows如何进行基准测试以找到确切的数字。
    总结:WORKERS_NUM乘以 RAILS_MAX_THREADS为您提供了 puma 可以处理的最大并发连接数。如果数量太少,您的用户将在负载高峰期间看到超时。为了在使用 MRI 的情况下获得最佳性能,您需要设置 WORKERS_NUM到核心数并找到最佳 RAILS_MAX_THREADS基于性能测试期间的平均响应时间。

    关于multithreading - RAILS_MAX_THREADS 是 Puma 会在构建时设置和缩放的东西,还是我应该设置它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43640261/

    相关文章:

    java - Android:WAITING线程完成执行该方法

    node.js - npm ERR cb() 从未调用

    ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序

    Turbolinks 缓存前后的 Javascript DOM 事件

    ruby-on-rails - Heroku 上的 "Missing ` secret_key_base ` for ' 生产 ' environment"错误

    java - 什么可能导致并行 Java 程序运行时间相差很大?

    C++ Tensorflow,如何使用多线程制作session-> Run(),或者花费更少的时间

    c# - 问题: Multithread bulkinsert

    java - 声明回调;仅当部署到 Heroku 时,SQL 语法才错误

    node.js - React App在本地运行,但在Heroku上崩溃并显示错误代码= H10