2013-01-17 12 views
11

I miei utenti vedono timeout di richieste occasionali su Heroku. Sfortunatamente non riesco a riprodurli costantemente, il che li rende davvero difficili da debugare. Ci sono molte opportunità per migliorare le prestazioni, ad es. riducendo l'enorme numero di query di database per richiesta e aggiungendo altro caching, ma senza il profiling che è una soluzione al buio.Come silenziare i timeout H12 incoerenti su Heroku

Secondo le nostre analisi New Relic, molte richieste richiedono tra 1 e 5 secondi sul server. So che è troppo lento, ma non è vicino ai 30 secondi necessari per il timeout.

La scheda di errore su New Relic mostra diverse query di database in cui si verifica il timeout, ma queste non sono query particolarmente lente e possono essere query diverse per ogni arresto anomalo. Anche per lo stesso URL a volte lo fa e a volte non mostra una query del database.

Come scoprire che cosa succede in questi casi particolari? Per esempio. come vedo quanto tempo è stato speso nel database quando si è verificato il timeout, a differenza del tempo che trascorre nel database quando non ci sono errori?

Un'ipotesi che ho è che il database viene bloccato in alcuni casi; forse una combinazione di lettura e scrittura.

+0

Hai visto i registri?La prossima volta che si verifica il problema, vai immediatamente al tuo prompt dei comandi e inserisci "registri heroku". La registrazione dei log dall'errore ci aiuterà a risolvere il problema. –

+0

@BrianPetro Ho i log, ma sono diversi per ogni caso - anche sulla stessa pagina - perché termina in un posto diverso tutto il tempo. Ecco perché sto cercando un modo più generico per eseguire il debug di questo. –

+0

Aggiorna il post con alcuni registri o il codice più pertinente. Altrimenti temo di non poter essere di grande aiuto. –

risposta

7

Forse l'hai già visto, ma Heroku ha uno doc con qualche buon background sui timeout delle richieste.

Se le richieste impiegano molto tempo ei processi che li gestiscono non vengono uccisi prima che le richieste vengano completate, devono generare tracce di transazione che forniscano dettagli sulle singole transazioni che hanno richiesto troppo tempo.

Se stai usando Unicorn, è possibile che questo non sta accadendo perché le richieste stanno prendendo abbastanza a lungo che stanno colpendo contro Unicorn di timeout (dopo di che i lavoratori a servizio tali richieste saranno forzatamente uccisi, non dando il Nuovo agente Relic abbastanza tempo per riferire in).

mi consiglia un approccio in due fasi:

  1. Configurare il rack-timeout middleware ad avere un timeout di sotto 30s timeout di Heroku. Se funziona, interromperà le richieste impiegando più tempo del timeout sollevando un Timeout::Error e tali richieste dovrebbero generare tracce di transazione in New Relic.
  2. Se ciò non produce nulla (il che potrebbe, perché rack-timeout si basa sulla classe stdlib di Ruby Timeout, che ha some limitations), puoi provare a eseguire il bump del timeout di gestione delle richieste Unicorn dal suo valore predefinito di 60 s (supponendo che tu stia usando Unicorn). Tieni presente che le richieste di lunga durata legheranno un lavoratore Unicorn per un periodo più lungo in questo caso, il che potrebbe rallentare ulteriormente il tuo sito, quindi utilizzalo come ultima risorsa.
1

Due anni in ritardo. Ho una minima esperienza con Ruby, ma per Django il problema con Gunicorn è che non gestisce correttamente i client lenti su Heroku perché le richieste non sono pre-buffer, il che significa che una connessione al server potrebbe essere lasciata in attesa (blocco). This might be a helpful article to you, sebbene si applichi principalmente a Gunicorn e Python.