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
Ответы
Ответ 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
К моему контроллеру приложений и он решил мою проблему.
Эта конструкция называется фильтром и оценивается после каждого запроса.
Я не уверен, что на самом деле происходит с приложением, но я подозреваю, что соединения не закрываются после каждого запроса.
Ответ 5
Эта ссылка может быть полезна для вас.
https://devcenter.heroku.com/articles/concurrency-and-database-connections