Подтвердить что ты не робот

ActiveRecord:: ConnectionTimeoutError происходит спорадически

Всякий раз, когда у меня есть приложение, использующее ActiveRecord, я получаю этот ConnectionTimeoutError - но всегда после некоторого неизвестного периода времени

ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5 seconds.  The max pool size is currently 30; consider increasing it.):

Ранее было установлено значение 5, мы уже увеличили его, и он не может одновременно использовать 30 подключений. Единственное, что мы используем для ActiveRecord, это наш магазин сеансов.

Наш файл database.yml выглядит так:

development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 30
  timeout: 5000

(тестовые и производственные настройки одинаковы)


Я искал это событие и просто наткнулся на это сообщение:

https://groups.google.com/forum/#!msg/copenhagen-ruby-user-group/GEHgi_WudmM/gnCiwWqmVfMJ

Что означает, что ActiveRecord не проверяет соединение обратно в пул после его завершения? Это правда? Нужно ли мне вручную управлять соединениями?

Я ценю любые советы!

edit Возможно, мне стоит упомянуть, что я запускаю Rails 3.1.3

4b9b3361

Ответ 1

Rails имеет промежуточное программное обеспечение под названием ActiveRecord::ConnectionAdapters::ConnectionManagement, которое очищает активные соединения по каждому запросу, чтобы они не склеивались. Проверьте свое промежуточное ПО, чтобы убедиться, что у вас есть это (что есть по умолчанию), запустите "rake middleware". Вам не нужно вручную управлять подключениями, чтобы ответить на ваш последний вопрос.

Запустите это в консоли

   ActiveRecord::Base.clear_active_connections!

Ответ 2

Я использовал этот код в своем приложении Sinatra

after do
  ActiveRecord::Base.clear_active_connections!
end   

Это решает мою проблему

Ответ 3

Применяется также к Rails 5, поскольку Puma является сервером по умолчанию.

Если вы используете Threaded Servers, такие как Puma, Phushion Passenger, они создают несколько потоков одного и того же приложения. Таким образом, ваше приложение запускается быстрее, одновременно выполняя каждый входящий запрос.

Убедитесь, что размер пула равен или больше количества потоков. У меня возникла проблема, когда некоторые из моих потоков давали мне ActiveRecord::ConnectionTimeoutError, и проблема была неопределенной, поскольку она происходит раз в то время не очень часто.

Ответ 4

У меня также возникла аналогичная проблема с приложением Sinatra, я добавил

after do
  ActiveRecord::Base.clear_active_connections!
end 

К моему контроллеру приложений и он решил мою проблему.

Эта конструкция называется фильтром и оценивается после каждого запроса.

Я не уверен, что на самом деле происходит с приложением, но я подозреваю, что соединения не закрываются после каждого запроса.