Non uno strumento specifico, ma piuttosto una tecnica di debug per rintracciare quale codice è responsabile per le connessioni aperte o altre risorse.
Suppongo che si stia utilizzando un metodo coerente sul lato java per ottenere una connessione db (raggruppata o meno non importa).
L'idea è di creare una classe wrapper molto leggera attorno al tuo factory/pool di connessione o qualunque cosa sia.Il wrapper implementerà qualsiasi interfaccia jdbc ha senso in modo da poterlo scambiare per il normale oggetto di connessione, ma la maggior parte dei metodi chiamerà/restituirà la connessione sottostante in modo trasparente.
Se si utilizza una sorta di framework IoC (ad esempio la primavera) si dovrebbe essere in grado di scambiare facilmente la connessione/factory class a un livello di configurazione. Ora tutto il tuo codice java utilizzerà il tuo nuovo wrapper di connessione db.
Se si sta utilizzando un pool, chiamare connection.close()
in genere restituisce l'oggetto al pool anziché distruggere la connessione. Quindi questa tecnica funziona per perdite di connessione normali o perdite "non restituite al pool (pool esaurito)".
Ora dobbiamo solo registrare i bit interessanti e impostare una trappola per le connessioni trapelate.
Stack trace per identificare creatore
Nel costruttore o il metodo factory per il vostro involucro di connessione creare un nuovo oggetto Throwable
e conservarlo come variabile locale all'interno del vostro involucro per più tardi. Usiamo un Throwable
perché è più veloce/economico rispetto all'utilizzo di Thread.currentThread().getStackTrace()
.
Impostare la "trappola"
implementare il metodo finally
nella classe wrapper. Questo è un metodo di pulizia chiamato dal GC quando l'oggetto viene distrutto perché non viene più utilizzato.
Il metodo finally
deve verificare "sono chiuso?". Se è già chiuso, allora è tutto a posto ... tuttavia se la connessione è in GC e non è stata chiusa ... allora questa è una connessione "perduta".
Ora il Throwable
ritorna in gioco. Siamo in grado di afferrare il Throwable
e di produrre un bel messaggio di registro che dice qualcosa del tipo: "Sono una connessione trapelata e qui c'è una traccia dello stack che coinvolge il mio creatore".
Espandendo l'idea
Questo metodo può essere adattato per una varietà di situazioni. Puoi naturalmente conservare altri tipi di dati nel tuo wrapper per risolvere il tuo problema specifico. Ad esempio il tempo di creazione. Quindi puoi eseguire il polling per connessioni a lunga durata e coinvolgere nuovamente il creatore. Oppure puoi eseguire il polling delle connessioni esistenti e analizzare le tracce dello stack Throwable
per ottenere dati su quale codice sta utilizzando quante connessioni nel tempo.
Probabilmente esiste uno strumento standard che può anche fare questo tipo di cose, ma la quantità di codice richiesta per applicare questa tecnica è molto minima nella maggior parte dei casi (presupponendo che tu abbia un modo semplice per scambiare il tuo db connection factory senza search-replaceing dell'intera codebase).
Mentre P6Spy è uno strumento piacevole, non vedo come possa essere utile ai problemi di perdita delle connessioni di caccia. –