Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Problema de conexão intermitente do Oracle JDBC


Há uma solução fornecida para esse problema em alguns fóruns da OTN (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989). Mas, a causa raiz do problema não é explicada. A seguir está minha tentativa de explicar a causa raiz do problema.

Os drivers Oracle JDBC se comunicam com o servidor Oracle de maneira segura. Os drivers usam o java.security.SecureRandom classe para reunir entropia para garantir a comunicação. Essa classe depende do suporte da plataforma nativa para coletar a entropia.

Entropia é a aleatoriedade coletada/gerada por um sistema operacional ou aplicativo para uso em criptografia ou outros usos que requerem dados aleatórios. Essa aleatoriedade geralmente é coletada de fontes de hardware, seja de ruídos de hardware, dados de áudio, movimentos do mouse ou geradores de aleatoriedade especialmente fornecidos. O kernel coleta a entropia e a armazena em um pool de entropia e disponibiliza os dados de caracteres aleatórios para os processos ou aplicativos do sistema operacional através dos arquivos especiais /dev/random e /dev/urandom .

Lendo de /dev/random drena o pool de entropia com a quantidade solicitada de bits/bytes, fornecendo um alto grau de aleatoriedade frequentemente desejado em operações criptográficas. No caso, se o pool de entropia for completamente drenado e entropia suficiente não estiver disponível, a operação de leitura em /dev/random blocos até que entropia adicional seja coletada. Devido a isso, os aplicativos que lêem de /dev/random pode bloquear por algum período de tempo aleatório.

Em contraste com o acima, a leitura do /dev/urandom não bloqueia. Lendo de /dev/urandom , também, drena o pool de entropia, mas quando falta entropia suficiente, ele não bloqueia, mas reutiliza os bits dos dados aleatórios parcialmente lidos. Diz-se que isso é suscetível a ataques criptoanalíticos. Esta é uma possibilidade teórica e, portanto, é desencorajado a leitura de /dev/urandom para reunir aleatoriedade em operações criptográficas.

O java.security.SecureRandom classe, por padrão, lê do /dev/random arquivo e, portanto, às vezes bloqueia por um período aleatório de tempo. Agora, se a operação de leitura não retornar por um período de tempo necessário, o servidor Oracle expira o cliente (os drivers jdbc, neste caso) e descarta a comunicação fechando o soquete de seu final. O cliente ao tentar retomar a comunicação após retornar da chamada de bloqueio encontra a exceção de E/S. Esse problema pode ocorrer aleatoriamente em qualquer plataforma, especialmente, onde a entropia é coletada de ruídos de hardware.

Conforme sugerido no fórum da OTN, a solução para esse problema é substituir o comportamento padrão de java.security.SecureRandom class para usar a leitura sem bloqueio de /dev/urandom em vez da leitura de bloqueio de /dev/random . Isso pode ser feito adicionando a seguinte propriedade do sistema -Djava.security.egd=file:///dev/urandom para a JVM. Embora essa seja uma boa solução para aplicativos como os drivers JDBC, ela é desencorajada para aplicativos que realizam operações criptográficas principais, como geração de chave criptográfica.

Outras soluções podem ser usar diferentes implementações de semeadores aleatórios disponíveis para a plataforma que não dependem de ruídos de hardware para coletar entropia. Com isso, você ainda pode precisar substituir o comportamento padrão de java.security.SecureRandom .

Aumentar o tempo limite do soquete no lado do servidor Oracle também pode ser uma solução, mas os efeitos colaterais devem ser avaliados do ponto de vista do servidor antes de tentar isso.