2016-04-14 6 views
6

Gemäß der API-Dokumentation ist der Rails Reaper dazu gedacht, Verbindungen von toten Threads zu finden und wiederherzustellen. Der Reaper wird basierend auf der reaping_-Frequenz ausgeführt.Rails Reaper funktioniert nicht

Ich stoße Fälle auf, wenn die Anzahl der Datenbankverbindungen die angegebene Grenze überschreitet und es Verbindungen im Leerlaufzustand gibt, aber der Reaper diese Verbindungen nicht zurücksetzt. Ich habe versucht, den Reaper manuell zu starten, aber es scheint keinen Effekt zu haben.

reaper = ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper.new(ActiveRecord::Base.connection, 10) 
reaper.run 

Dass es keine Wirkung hat wurde mit verifizierter

ActiveRecord::Base.connection.execute("SELECT * FROM pg_stat_activity WHERE pid <> pg_backend_pid()") 
PgHero.total_connections 

Ist das ein Fehler mit dem Schnitter in Active oder ist nicht gemeint, wie dies funktioniert? Wenn das der Fall ist, wie ist die Option, einen benutzerdefinierten Reaper zu schreiben, um tote Verbindungen wiederherzustellen? Das PG-Gem wird für die Verbindung mit Postgres db verwendet. Die Abfrage, die die Verbindungen auffressen wird, ist:

SHOW TRANSACTION ISOLATION LEVEL

Rails-Version: 4.2.3

pg gem Version: 0.17.1

Postgres Version: 9.4.6

Schienen App Server: Puma

+0

Haben Sie die PID der an die DB angeschlossenen Prozesse überprüft? Hast du sichergestellt, dass es keine toten Rubinprozesse gibt? Normalerweise müssen Sie keine Verbindungen selbst ernten. Machst du deinen Code falsch? Wie ist dein Puma aufgebaut? Du brauchst den richtigen 'before_fork' /' after_fork' Code in deiner Puma Konfiguration. –

+0

Können Sie uns Ihre Puma-Konfiguration geben, vor allem, wie viele Arbeiter und Threads verwenden Sie? Wie groß ist Ihr Verbindungspool in 'database.yml'? – BoraMa

Antwort

-1

Bitte den Code unten zu config/deploy.rb

deploy.task :restart, :roles => :app do 
    run "touch #{current_path}/tmp/restart.txt" 
end 

Fall 2 hinzufügen, wenn Capistrano verwendet wird (nur das Skript/Prozess Verzeichnis löschen):

versucht standardmäßig, Capistrano eine neue Rails den Schnitter Skript zu starten läuft . Sie sollten das Standardverhalten anpassen.

Angenommen, Sie verwenden Ihre Rails-App mit Passenger (mod_rails), installieren Sie das folgende Capistrano + Passenger (mod_rails) Rezept und Capistrano startet Ihre Passenger-Instanz beim Deployment neu.

+0

Es gibt kein Problem beim Neustart der App nach der Bereitstellung. Es wird nach jeder Bereitstellung neu gestartet. Auch läuft die App nicht auf Beifahrer sondern Puma. – Akarsh

0

Mongrel/Fahrgast Epoche und vor auf Rack-Aufbau ist, der einzige Weg, um eine Rails-Anwendung ausgeführt wurde mit CGI or FGCI. Das Skript/Reaper-Datei verwendet wurde, starten/einen Rails-Prozess zu stoppen.

Standardmäßig versucht Capistrano, einen neuen Rails-Prozess zu starten, der das Reaper-Skript ausführt. Sie sollten das Standardverhalten anpassen. Weitere Informationen finden Sie unter (https://simonecarletti.com/blog/2008/12/capistrano-deploy-recipe-with-passenger-mod_rails-taste/)

Capistrano wird Ihre Passenger-Instanz beim Deployment neu starten. erste

2

Ein paar Anmerkungen:

  • Es ist wahrscheinlich nicht die SHOW TRANSACTION ISOLATION LEVEL Abfrage, die „auffressen“ Ihre DB-Verbindungen ist. Die pg_stat_activity Ansicht zeigt einfach die aktive oder, in Ihrem Fall, die last query ausgeführt auf jeder Verbindung. Die wichtigeren Informationen aus den Statistiken sind also nur, dass zu viele Verbindungen offen sind.

  • Die ConnectionPool::Reaper befreit DB-Verbindungen, aber nur von den dead threads, das heißt, diese gestoppt oder unerwartet beendet. Es hat jedoch keine Auswirkungen auf aktive oder schlafende Threads. Die Tatsache, dass Reaper nicht für dich arbeitet IMO bedeutet einfach, dass diese Threads wahrscheinlich schlafen und nicht tot sind.

Nun kann es eine Reihe von Gründen geben, die max. erlaubten Verbindungen auf dem DB-Server:

  • Möglicherweise müssen zu viele Threads mit einer geprüften Verbindung mit dem db zugleich. Die ConnectionPool reserviert normalerweise eine Verbindung zur DB pro Thread, bis zur pool Größe konfiguriert in database.yml. Wenn Ihre Poolgröße also ziemlich groß ist und Sie viele Threads haben, können Sie die max. DB-Verbindungen. Zum Beispiel erstellt Puma bis zu 16 threads by default.

  • Jeder Rails-Prozess definiert seinen eigenen Verbindungspool. Wenn also beispielsweise Ihre Poolgröße als 10 definiert ist und Sie 10 Rails-Prozesse haben, können die Verbindungen zu db zu 10 * 10 = 100 Verbindungen führen. Puma-Server erlaubt multiple workers laufen (die separate Prozesse sind), so dass Sie möglicherweise zu viele Puma-Arbeiter ausgeführt haben. Die gleiche Logik gilt für alle Hintergrundprozesse und Threads. Sidekiq zum Beispiel erstellt standardmäßig bis zu 25 Threads für Hintergrundjobs. Wenn Sie also Threads in Ihrem Code oder einem beliebigen Juwel verwenden, das Threads intern verwendet, z. Für die Funktionalität von Hintergrundjobs müssen Sie die genaue Konfiguration kennen, damit Sie die maximale Anzahl von Verbindungen nicht überschreiten.

  • Sie könnten leiden unter db Verbindung Leckage. Der Puma-Server benötigt eine spezielle Konfiguration, wenn preload_app (App-Preloading) verwendet wird, so dass Datenbankverbindungen nicht verloren gehen. Dies ist z.B. here und here.

Verwandte Themen