簡體   English   中英

ActiveRecord :: ConnectionTimeoutError:無法在5.000秒內獲取數據庫連接(等待5.000秒)

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

我有一個生產中的rails應用程序,我前幾天部署了一些更改。 突然間,我得到錯誤ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)每天多次ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)並且必須重新啟動puma才能解決問題。

我完全不知道是什么導致了這一點。 我沒有更改我的服務器上的任何內容,我所做的更改非常簡單(添加到視圖並添加到控制器方法)。

我在日志文件中看不到任何東西。

我正在使用rails 4.1.4和ruby 2.0.0p481

有關為什么我的連接填滿的任何想法? 我的連接池設置為10,我使用默認的puma配置。

這是一個堆棧跟蹤:

ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)):
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:190:in `block in wait_poll'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `loop'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `wait_poll'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:136:in `block in poll'
  /usr/local/rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:146:in `synchronize'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:134:in `poll'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:418:in `acquire_connection'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:351:in `block in checkout'
  /usr/local/rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:350:in `checkout'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:265:in `block in connection'
  /usr/local/rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:264:in `connection'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:541:in `retrieve_connection'
  activerecord (4.1.4) lib/active_record/connection_handling.rb:113:in `retrieve_connection'
  activerecord (4.1.4) lib/active_record/connection_handling.rb:87:in `connection'
  activerecord (4.1.4) lib/active_record/query_cache.rb:51:in `restore_query_cache_settings'
  activerecord (4.1.4) lib/active_record/query_cache.rb:43:in `rescue in call'
  activerecord (4.1.4) lib/active_record/query_cache.rb:32:in `call'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.1.4) lib/active_support/callbacks.rb:82:in `run_callbacks'
  actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  airbrake (4.1.0) lib/airbrake/rails/middleware.rb:13:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.4) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.4) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.4) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  dragonfly (1.0.5) lib/dragonfly/cookie_monster.rb:9:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  activesupport (4.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  airbrake (4.1.0) lib/airbrake/user_informer.rb:16:in `_call'
  airbrake (4.1.0) lib/airbrake/user_informer.rb:12:in `call'
  railties (4.1.4) lib/rails/engine.rb:514:in `call'
  railties (4.1.4) lib/rails/application.rb:144:in `call'
  railties (4.1.4) lib/rails/railtie.rb:194:in `public_send'
  railties (4.1.4) lib/rails/railtie.rb:194:in `method_missing'
  puma (2.9.0) lib/puma/configuration.rb:71:in `call'
  puma (2.9.0) lib/puma/server.rb:490:in `handle_request'
  puma (2.9.0) lib/puma/server.rb:361:in `process_client'
  puma (2.9.0) lib/puma/server.rb:254:in `block in run'
  puma (2.9.0) lib/puma/thread_pool.rb:92:in `call'
  puma (2.9.0) lib/puma/thread_pool.rb:92:in `block in spawn_thread'

Puma init.d腳本

#!/bin/sh
# Starts and stops puma
#


case "$1" in
        start)
                su myuser -c  "source /etc/profile && cd /var/www/myapp/current && rvm gemset use myapp && puma -d -e production -b unix:///var/www/myapp/myapp_app.sock -S /var/www/myapp/myapp_app.state"
        ;;

        stop)
                su myuser -c "source /etc/profile && cd /var/www/myapp/current &&  rvm gemset use myapp && RAILS_ENV=production bundle exec pumactl -S /var/www/myapp/myapp_app.state stop"
        ;;

        restart)
                $0 stop
                $0 start
        ;;

        *)
                echo "Usage: $0 {start|stop|restart}"
                exit 1
esac

編輯

我想我最終縮小了 airbrake gem相關的問題並 使用設計方法current_useruser_signed_in? application_controller.rbbefore_action

這是我的應用程序控制器:

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :authenticate_user!, :get_new_messages 

  # Gets the unread messages for the logged in user
  def get_new_messages
    @num_new_messages = 0 # Initially set to 0 so login page, etc works
    # If the user is signed in, fetch the new messages
    if user_signed_in? # I also tried !current_user.nil?
      @num_new_messages = Message.where(:created_for => current_user.id).where(:viewed => false).count
    end
  end

...
end

如果我刪除if塊,我沒有問題。 自從我介紹了該代碼以來,我的應用程序似乎耗盡了連接。 如果我離開它, if阻塞到位並刪除airbrake gem,我的應用程序似乎運行得很好,只有我的database.yml文件中的池上設置了默認的5個連接。

編輯

我終於弄明白,如果我在config/environments/production.rb文件中注釋掉這行,那我就不會得到錯誤。我在config/environments/production.rb config.exceptions_app = self.routes 似乎應用程序控制器before_action中的自定義路由+設計是原因。 我在github上創建了一個問題和一個可重現的項目。

https://github.com/plataformatec/devise/issues/3422 https://github.com/toymachiner62/devise-connection-failure/blob/master/config/environments/production.rb#L84

我遇到了與數據庫打開過多連接導致的相同問題。 當您在控制器外部(在模型,郵件程序,pdf生成器......中)進行數據庫查詢時,可能會發生這種情況。

我可以通過在這個塊中包裝這些查詢來自動關閉連接來修復它。

ActiveRecord::Base.connection_pool.with_connection do
  # your code
end

由於Puma工作多線程,因此池大小(如提到的eabraham)也可能是一個限制。 嘗試增加它(一點點)......

我希望這有幫助!

在設計家伙的幫助下,我想我終於弄明白了這個問題。 似乎通過使用自己的控制器自定義錯誤頁面,我沒有跳過before_action get_new_messages 所以非常簡單的解決方法是添加:

skip_before_filter :get_new_messages

到我的自定義錯誤控制器

這個問題詳細解釋了這背后的原因: https//github.com/plataformatec/devise/issues/3422

最終這個問題仍然困擾着我一年左右。 我終於通過與美洲獅人一起工作得到了很好的解決方案。

將你的美洲獅升級到至少2.15.x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM