2015-01-06 7 views
21

Ich habe eine Rails-App in Produktion, die ich einige Änderungen auf den anderen Tag eingesetzt habe. Plötzlich bekomme ich den Fehler ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds) mehrmals am Tag und muss Puma neu starten, um das Problem zu beheben.ActiveRecord :: ConnectionTimeoutError: konnte keine Datenbankverbindung innerhalb von 5.000 Sekunden erhalten (5000 Sekunden gewartet)

Ich bin völlig ratlos, was das verursacht. Ich habe nichts auf meinem Server geändert und die Änderungen, die ich vorgenommen habe, waren ziemlich einfach (fügen Sie eine Ansicht hinzu und fügen Sie sie zu einer Controller-Methode hinzu).

Ich sehe nicht viel von etwas in den Protokolldateien.

Ich bin mit Schienen 4.1.4 und Rubin 2.0.0p481

Irgendwelche Ideen, warum meine Verbindungen füllen sich? Mein Verbindungspool ist auf 10 eingestellt und ich verwende die Standard-Puma-Konfiguration.

Hier ist ein Stack-Trace:

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 Skript

#!/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 

EDIT

ich ich denke, habe schließlich das Problem eingrenzen sein mit der airbrake gem und mit der devise Methode current_user oder user_signed_in? in application_controller.rb in einer before_action.

Hier ist meine Anwendung Controller:

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 

Wenn ich den if Block zu entfernen, ich habe keine Probleme. Seit ich diesen Code eingeführt habe, scheint meine App keine Verbindungen mehr zu haben. Wenn ich diesen if Block an Ort und Stelle lasse und den Airbrake-Edelstein entferne, scheint meine App gut zu funktionieren, nur die Standard-5-Verbindungen, die in meinem Pool in meiner database.yml-Datei festgelegt sind.

EDIT

ich herausfinden, schließlich, dass, wenn ich diese Zeile in meiner config/environments/production.rb Datei auf Kommentar config.exceptions_app = self.routes, die ich habe nicht den Fehler. Es scheint, dass benutzerdefinierte Routen + Devices im App-Controller before_action die Ursache sind. Ich habe ein Problem und ein reproduzierbares Projekt auf GitHub erstellt.

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

+0

Ist das relevant? http://stackoverflow.com/questions/24911838/rails-4-database-connection-pool-error –

+0

Es könnte relevant sein, aber die komische Sache ist, dass ich keine Probleme wie diese für ein Jahr hatte und ich habe Änderungen im letzten Jahr implementiert. Der andere Tag ist das erste Mal, dass ich dieses Problem hatte. – Catfish

+0

Wie viele Puma-Threads laufen Sie? Haben Sie auch Arbeiter (sidekiq, spacedJob usw.)? – eabraham

Antwort

2

Mit Hilfe der Entwickler Jungs 'Ich denke, ich habe endlich dieses Problem herausgefunden. Es sah so aus, als würde ich bei Verwendung von benutzerdefinierten Fehlerseiten mit seinem eigenen Controller die before_action get_new_messages nicht überspringen. Also die sehr einfache Lösung war hinzuzufügen:

skip_before_filter :get_new_messages 

zu meinem benutzerdefinierten Fehler-Controller.

Dieses Problem erklärt im Detail, den Grund für diese: https://github.com/plataformatec/devise/issues/3422

6

hatte ich die gleichen Probleme, die die Datenbank auch durch zu viele offene Verbindungen verursacht wurden. Dies kann passieren, wenn Sie Datenbankabfragen außerhalb eines Controllers haben (in einem Modell, Mailer, PDF-Generator, ...).

Ich könnte es reparieren, indem Sie diese Abfragen in diesem Block, der die Verbindung automatisch schließt.

Da Puma multi-threaded arbeitet, kann die Poolgröße (wie von eabraham erwähnt) auch eine Einschränkung darstellen. Versuchen Sie es zu erhöhen (ein wenig) ...

Ich hoffe, das hilft!

0

Letztes Ende dieses Problem geplagt mich noch für ein weiteres Jahr oder so. Ich habe endlich eine gute Lösung von der Arbeit mit den Puma-Jungs bekommen.

Aktualisieren Sie Ihren Puma auf mindestens 2.15.x.

+2

das Problem besteht immer noch. Mit welchen Rubin- und Puma-Versionen befindest du dich gerade? Ich bin auf 'JRuby 9.1.2.0' und' Puma 3.4.0'. – oozzal

+0

Ich bin immer noch auf Puma 2.15.x und ich laufe MRI-Version von Ruby glaube ich. Definitiv nicht auf JRuby. Wahrscheinlich Version 2.1.x oder 2.2.x. – Catfish

+0

@oozzal Ich bekomme die gleichen Fehler. Hast du das gelöst? – bibstha