为什么我们在 Heroku 上没有数据库连接?

Why are we out of database connections on Heroku?

我们在 Heroku 上有一个带有 Sidekiq 的 Rails 应用程序,并且 运行 没有数据库连接。

ActiveRecord::ConnectionTimeoutError: could not obtain a database  
connection within 5.000 seconds (waited 5.000 seconds)

Heroku 的东西:

Database plan: Standard0 (120 connections)

Web dynos: 2 Standard-2X

Worker dynos: 1 Standard-2X

heroku 配置:

MAX_THREADS: 5
(DB_POOL not set)
(WEB_CONCURRENCY not set)

过程文件:

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq

database.yml:

...

production:
  url:  <%= ENV["DATABASE_URL"] %>
  pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %>

puma.rb:

# https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#adding-puma-to-your-application

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 2)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end

sidekiq.yml:

---
:concurrency: 25
:queues:
  - [default]

我们还有一些每 10 分钟触发一次的 rake 任务,它们会在一两秒内完成。

当我们在 sidekiq 中进行大量消息处理时,问题似乎会发生。我们做类似的事情:

  1. 从第 3 方网络服务获取文章标题
  2. 在单个事务中将每个标题插入数据库
  3. 在 sidekiq 中为每个标题创建一条消息 (worker.perform_async)
  4. 处理每条消息,点击一个端点以获取 body 并更新 body(可能需要 .5 - 3 秒)

当发生第 4 次时,我们看到了连接问题。

我的理解是我们的上述配置远远低于连接限制,但是我们做错了什么吗?有什么东西正在消耗游泳池吗?任何帮助都会很棒,谢谢。

来源:

您正在 25 个 Sidekiq 线程之间共享 5 个数据库连接。设置 DB_POOL 为 25 或者 Sidekiq 的并发数为 5.