我知道 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
,所以线程数是恒定的。如果您将它们设置为不同,它将从最小值缩放到最大值,但我还没有在野外看到它。限制线程数的原因有很多——你的解释器和响应时间:
还有一个论点认为慢速 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/