Puma 和 Rails 的线程安全问题

Thread safe issue with Puma and Rails

提问人:Julien 提问时间:11/4/2023 最后编辑:Julien 更新时间:11/4/2023 访问量:19

问:

我有一个在 Puma 上运行的 Rails 4 应用程序,当流量过多时,我几乎在任何请求上都会遇到很多以下错误:

Error: can't add a new key into hash during iteration

下面是一个示例堆栈跟踪:

vendor/cache/ruby/2.6.0/gems/thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:16:in `[]='
vendor/cache/ruby/2.6.0/gems/thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:13:in `block in []='
vendor/cache/ruby/2.6.0/gems/thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:13:in `synchronize'
vendor/cache/ruby/2.6.0/gems/thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:13:in `[]='
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/template/resolver.rb:49:in `block in <class:Cache>'
vendor/cache/ruby/2.6.0/gems/thread_safe-0.3.6/lib/thread_safe/cache.rb:43:in `[]'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/template/resolver.rb:61:in `cache'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/template/resolver.rb:151:in `cached'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/template/resolver.rb:115:in `find_all'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:70:in `block (2 levels) in _find_all'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:66:in `each'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:66:in `block in _find_all'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:65:in `each'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:65:in `_find_all'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:54:in `find_all'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/path_set.rb:46:in `find'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/lookup_context.rb:121:in `find'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/renderer/partial_renderer.rb:418:in `find_template'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/renderer/partial_renderer.rb:413:in `find_partial'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/renderer/partial_renderer.rb:294:in `render'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/renderer/renderer.rb:51:in `render_partial'
vendor/cache/ruby/2.6.0/gems/actionview-4.2.11.1/lib/action_view/helpers/rendering_helper.rb:35:in `render'

我想这可能与彪马工人和缓存有关?

彪马配置:

workers 3
preload_app!

# Min and Max threads per worker
threads 1, 6

app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"

# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"

# Logging
if rails_env == "production"
  stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
end

# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"

on_worker_boot do
  #reconnect to mongo
  Mongoid::Clients.clients.each do |name, client|
    client.close
    client.reconnect
  end

  #reconnect to redis
  $redis.redis.client.reconnect
end

before_fork do
  Mongoid.disconnect_clients
end

知道为什么会发生这种情况以及我该如何防止它吗?

Ruby-on-Rails 螺纹安全 彪马

评论


答: 暂无答案