2016-04-14 21 views
6

Come per i documenti API, il ratch rails ha lo scopo di trovare e recuperare le connessioni dai thread morti. Il mietitore viene eseguito in base alla frequenza di reaping_.Reaper Reaper not working

Sto riscontrando casi in cui il numero di connessioni al database sta superando il limite specificato e ci sono connessioni in stati di inattività, ma il mietitore non sta resettando quelle connessioni. Ho provato a far funzionare il mietitore manualmente ma non sembra avere alcun effetto.

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

Che non ha alcun effetto sono stati verificati utilizzando

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

Si tratta di un bug con il mietitore in ActiveRecord o non è pensata per lavorare in questo modo? In questo caso, qual è l'opzione per scrivere un mietitore personalizzato per recuperare le connessioni non funzionanti? La gemma pg viene utilizzata per la connessione a postgres db. La query che sta mangiando le connessioni è:

MOSTRA DI ISOLAMENTO DI TRANSAZIONE LIVELLO

Rails versione: 4.2.3

versione pg gemma: 0.17.1

versione

Postgres: 9.4.6

Rails app server: Puma

+0

hai controllato il PID dei processi connessi al DB? Ti sei assicurato che non ci siano processi di rubini morti? Di solito non devi raccogliere le connessioni da solo. Fai qualche biforcazione nel tuo codice? Come è impostato il tuo puma? Avrai bisogno del giusto codice 'before_fork' /' after_fork' nella configurazione di puma. –

+0

Puoi darci la tua configurazione puma, in particolare quanti lavoratori e fili usi? Quanto è grande la configurazione del tuo pool di connessione in 'database.yml'? – BoraMa

risposta

-1

invitiamo ad aggiungere il codice sottostante per config/deploy.rb

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

Caso 2 se si utilizza Capistrano (basta cancellare la directory script/processo):

Per impostazione predefinita, Capistrano cerca di avviare una nuova Rails processo in esecuzione lo script Reaper . È necessario personalizzare il comportamento predefinito.

Supponendo di eseguire l'app Rails utilizzando Passenger (mod_rails), installare la seguente ricetta Capistrano + Passenger (mod_rails) e Capistrano eseguirà correttamente il riavvio dell'istanza di Passenger in fase di distribuzione.

+0

Non c'è alcun problema nel riavvio dell'app dopo la distribuzione. Viene riavviato dopo ogni distribuzione. Inoltre, l'app non è in esecuzione su passeggero ma su Puma. – Akarsh

0

Epoca Mongola/Passeggero e prima di essere creata su Rack, l'unico modo per eseguire un'applicazione Rails era l'utilizzo di CGI or FGCI. Il file script/mietitore era utilizzato per avviare/arrestare un processo Rails.

Per impostazione predefinita, Capistrano tenta di avviare un nuovo processo Rails che esegue lo script del mietitore. È necessario personalizzare il comportamento predefinito. Si prega di fare riferimento, (https://simonecarletti.com/blog/2008/12/capistrano-deploy-recipe-with-passenger-mod_rails-taste/)

Capistrano riavvierà con garbo l'istanza di Passenger in fase di distribuzione.

2

Un paio di note prima:

  • Non è probabilmente la query SHOW TRANSACTION ISOLATION LEVEL che sta "mangiando" le connessioni db. La vista pg_stat_activity mostra semplicemente l'attivo o, nel tuo caso, il last query eseguito su ciascuna connessione. Quindi le informazioni più importanti dalle statistiche sono che ci sono troppe connessioni aperte.

  • Il ConnectionPool::Reaper consente di liberare connessioni db ma solo dal dead threads, cioè quelle fermato o terminato inaspettatamente. Ma non influisce sulle connessioni attive o sui thread dormienti. Il fatto che Reaper non funzioni per te IMO significa semplicemente che quei thread probabilmente stanno dormendo, non sono morti.

Ora, ci possono essere una serie di motivi per il superamento del limite massimo. connessioni consentite sul server db:

  • Si potrebbe avere troppi thread con un collegamento controllato per il db allo stesso tempo. Lo ConnectionPool normalmente riserva una connessione al db per thread, fino alla dimensione pool configurata in database.yml. Quindi se la dimensione del pool è piuttosto grande e hai molti thread, puoi superare il limite massimo. connessioni db. Ad esempio, puma crea fino a 16 threads by default.

  • Ogni processo di rotaie definisce il proprio pool di connessioni. Quindi se ad esempio la dimensione del pool è definita come 10 e si hanno 10 processi di binari, le connessioni a db possono generare connessioni fino a 10 * 10 = 100. Il server Puma consente di eseguire multiple workers (che sono processi separati), pertanto è possibile che siano in esecuzione troppi puma worker.

  • La stessa logica si applica a tutti i processi e i thread in background. Sidekiq, ad esempio, per impostazione predefinita crea fino a 25 thread per i lavori in background. Pertanto, se utilizzi thread nel codice o in qualsiasi gemma che utilizza internamente i thread, ad es. per la funzionalità dei lavori in background, è necessario essere consapevoli della loro impostazione precisa in modo da non superare il numero massimo di connessioni.

  • Potrebbe verificarsi una perdita di connessione db. Il server Puma necessita di un'impostazione speciale quando viene utilizzato preload_app (precaricamento app) in modo che le connessioni db non siano trapelate. Questo è documentato per es. here e here.