Rails 6.1.5在Heroku中动态设置DB Pool大小不生效问题
问题解决:Rails 6.1.5 + Heroku 不同进程DB_POOL配置不生效
核心原因
Rails启动时会一次性初始化数据库连接池,Sidekiq worker进程启动时Rails已完成初始化,默认不会重新读取DB_POOL变量;另外若database.yml未正确使用ERB语法,环境变量读取会失效。
分步解决方案
1. 修正database.yml的ERB语法
确保连接池大小通过ERB解析环境变量,而不是直接写字符串:
# config/database.yml default: &default adapter: postgresql pool: <%= ENV.fetch("DB_POOL", 5) %> timeout: 5000 production: <<: *default url: <%= ENV.fetch("DATABASE_URL") %>
2. 强制Sidekiq worker进程重新初始化连接池
在Sidekiq初始化文件中,同步DB_POOL与并发数并重建连接池:
# config/initializers/sidekiq.rb Sidekiq.configure_server do |config| concurrency = ENV.fetch("SIDEKIQ_CONCURRENCY", 15).to_i config.concurrency = concurrency # 覆盖DB_POOL并重建连接池 db_pool = ENV.fetch("DB_POOL", concurrency.to_s).to_i ActiveRecord::Base.establish_connection( ActiveRecord::Base.configurations[Rails.env].merge(pool: db_pool) ) end
3. 确保Procfile环境变量正确传递
Procfile中的变量需要让shell正确展开,保持原有配置即可:
# Procfile web: DB_POOL=$RAILS_MAX_THREADS bundle exec puma -C config/puma.rb worker: DB_POOL=$SIDEKIQ_CONCURRENCY bundle exec sidekiq
4. 验证配置生效
使用双引号让shell解析变量,启动控制台测试:
heroku run "DB_POOL=15 bundle exec rails c"
在控制台执行以下命令确认连接池大小:
ActiveRecord::Base.connection_pool.size # 应返回15
5. 排查潜在覆盖配置
检查config/environments/production.rb,删除可能覆盖连接池大小的代码:
# 若存在该行,删除 # config.active_record.connection_pool_size = 5
内容的提问来源于stack exchange,提问作者ToddT
相关产品推荐
相关产品推荐

