Oracle
 sql >> Database >  >> RDS >> Oracle

Problema di connessione intermittente Oracle JDBC

È stata fornita una soluzione a questo problema in alcuni forum OTN (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989). Ma la causa principale del problema non è spiegata. Di seguito è riportato il mio tentativo di spiegare la causa principale del problema.

I driver Oracle JDBC comunicano con il server Oracle in modo sicuro. I driver utilizzano java.security.SecureRandom classe per raccogliere entropia per proteggere la comunicazione. Questa classe si basa sul supporto della piattaforma nativa per raccogliere l'entropia.

Entropia è la casualità raccolta/generata da un sistema operativo o da un'applicazione per l'uso in crittografia o altri usi che richiedono dati casuali. Questa casualità viene spesso raccolta da fonti hardware, dai rumori hardware, dai dati audio, dai movimenti del mouse o da generatori di casualità appositamente forniti. Il kernel raccoglie l'entropia e la memorizza come un pool di entropia e rende disponibili i dati dei caratteri casuali ai processi o alle applicazioni del sistema operativo tramite i file speciali /dev/random e /dev/urandom .

Lettura da /dev/random drena il pool di entropia con la quantità richiesta di bit/byte, fornendo un alto grado di casualità spesso desiderato nelle operazioni crittografiche. Nel caso, se il pool di entropia è completamente drenato e non è disponibile entropia sufficiente, l'operazione di lettura su /dev/random blocchi fino a quando non viene raccolta ulteriore entropia. Per questo motivo, le applicazioni leggono da /dev/random potrebbe bloccarsi per un periodo di tempo casuale.

In contrasto con quanto sopra, leggendo da /dev/urandom non blocca. Lettura da /dev/urandom , inoltre, drena il pool di entropia ma quando è a corto di entropia sufficiente, non blocca ma riutilizza i bit dai dati casuali parzialmente letti. Si dice che questo sia suscettibile di attacchi crittoanalitici. Questa è una possibilità teorica e quindi è sconsigliato leggere da /dev/urandom per raccogliere casualità nelle operazioni crittografiche.

java.security.SecureRandom class, per impostazione predefinita, legge da /dev/random file e quindi a volte si blocca per un periodo di tempo casuale. Ora, se l'operazione di lettura non viene restituita per un periodo di tempo richiesto, il server Oracle esegue il timeout del client (i driver jdbc, in questo caso) e interrompe la comunicazione chiudendo il socket dalla sua estremità. Il client quando tenta di riprendere la comunicazione dopo il ritorno dalla chiamata di blocco incontra l'eccezione IO. Questo problema può verificarsi in modo casuale su qualsiasi piattaforma, in particolare dove l'entropia viene raccolta dai rumori hardware.

Come suggerito nel forum OTN, la soluzione a questo problema è ignorare il comportamento predefinito di java.security.SecureRandom classe per utilizzare la lettura non bloccante da /dev/urandom invece del blocco letto da /dev/random . Questo può essere fatto aggiungendo la seguente proprietà di sistema -Djava.security.egd=file:///dev/urandom alla JVM. Sebbene questa sia una buona soluzione per applicazioni come i driver JDBC, è sconsigliata per applicazioni che eseguono operazioni crittografiche di base come la generazione di chiavi crittografiche.

Altre soluzioni potrebbero consistere nell'utilizzare diverse implementazioni di seminatrici casuali disponibili per la piattaforma che non si basano su rumori hardware per raccogliere entropia. Con questo, potresti comunque dover sovrascrivere il comportamento predefinito di java.security.SecureRandom .

Anche aumentare il timeout del socket sul lato server Oracle può essere una soluzione, ma gli effetti collaterali dovrebbero essere valutati dal punto di vista del server prima di tentare questa operazione.