Hier soir, j'ai quitté le bureau avec un programme Java Java écrit par moi. Il devrait insérer beaucoup d'enregistrements dans notre base de données d'entreprise (Oracle) à l'aide d'une connexion JDBC. Ce matin, lorsque je suis revenu à travail j'ai vu cette erreur (rattrapée par un try-catch):
Java.sql.SQLRecoverableException: I/O Exception: Connection reset
Le programme a écrit presque tous les enregistrements avant d'avoir ce problème, mais que se passe-t-il si cela se produit tôt (quelques minutes après avoir quitté le bureau le soir)? Je ne peux pas comprendre ce qui s'est passé, j'ai contacté mon administrateur de base de données et il a dit qu'il n'y avait pas de problème particulier sur la base de données.
Une idée de ce qui s'est passé et que puis-je faire pour l'éviter?
Cela signifie simplement que quelque chose dans le backend (SGBD) a décidé d'arrêter de fonctionner en raison de l'indisponibilité des ressources, etc. Cela n'a rien à voir avec votre code ou le nombre d'insertions. Vous pouvez en savoir plus sur des problèmes similaires ici:
Cela ne répondra peut-être pas à votre question, mais vous comprendrez pourquoi cela pourrait se produire. Vous pouvez discuter davantage avec votre administrateur de base de données et voir s'il y a quelque chose de spécifique dans votre cas.
L'erreur se produit sur certaines distributions RedHat. La seule chose que vous devez faire est d'exécuter votre application avec le paramètre Java.security.egd = file: /// dev/urandom:
Java -Djava.security.egd=file:///dev/urandom [your command]
Je veux produire une réponse complémentaire de la solution de nacho-soriano ...
J'ai récemment cherché à résoudre un problème où une application écrite Java (un travail Talend ELT en fait) veut se connecter à une base de données Oracle (11g et plus) puis échoue de manière aléatoire. Le système d'exploitation est à la fois RedHat Enterprise et CentOS. Le travail s’exécute très rapidement (pas plus d’une demi-minute) et se produit très souvent (environ un cycle toutes les 5 minutes).
Parfois, pendant la nuit comme temps de travail, pendant l'utilisation intensive de la base de données comme utilisation paresseuse, dans un mot au hasard, la connexion échoue avec ce message:
Exception in component tOracleConnection_1
Java.sql.SQLRecoverableException: Io exception: Connection reset
at Oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.Java:101)
at Oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.Java:112)
at Oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.Java:173)
at Oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.Java:229)
at Oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.Java:458)
at Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:411)
at Oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.Java:490)
at Oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.Java:202)
at Oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.Java:33)
at Oracle.jdbc.driver.OracleDriver.connect(OracleDriver.Java:465)
at Java.sql.DriverManager.getConnection(DriverManager.Java:664)
at Java.sql.DriverManager.getConnection(DriverManager.Java:208)
and StackTrace follow ...
Comme détaillé ici
La connexion Oracle a besoin de quelques nombres aléatoires pour assumer un bon niveau de sécurité. Le générateur de nombres aléatoires Linux produit des bases de nombres, l'activité du clavier et de la souris (entre autres) et les place dans une pile. Vous m'accorderez, sur un serveur, il n'y a pas une grande quantité d'une telle activité. Il peut donc arriver que les logiciels utilisent un nombre plus aléatoire que ce que le générateur peut produire.
Lorsque le pool est vide, les lectures de/dev/random seront bloquées jusqu'à ce que du bruit environnemental supplémentaire soit collecté. Et la connexion Oracle tombe en timeout (60 secondes par défaut).
La solution est de donner deux paramètres donnés à la JVM lors du démarrage:
-Djava.security.egd=file:/dev/./urandom
-Dsecurerandom.source=file:/dev/./urandom
Remarque: le '/./' est important, ne le laissez pas tomber!
La ligne de commande de lancement pourrait donc être:
Java -Djava.security.egd=file:/dev/./urandom -Dsecurerandom.source=file:/dev/./urandom -cp <classpath directives> appMainClass <app options and parameters>
Un inconvénient de cette solution est que les nombres générés sont un peu moins sûrs car l'aléatoire est impacté. Si vous ne travaillez pas dans une industrie militaire ou secrète, cette solution peut être votre solution.
Comme expliqué ici
Les deux directives données dans la solution 1 peuvent être placées dans Java fichier de paramètres de sécurité.
Jeter un coup d'œil à $Java_HOME/jre/lib/security/Java.security
Changer la ligne
securerandom.source=file:/dev/random
à
securerandom.source=file:/dev/urandom
Le changement prend effet immédiatement pour les nouvelles applications en cours d'exécution.
Quant à la solution # 1, un inconvénient de cette solution est que les nombres générés sont un peu moins sûrs car l'aléatoire est impacté. Cette fois, c'est un impact JVM global. Quant à la solution n ° 1, si vous ne travaillez pas dans une industrie militaire ou secrète, cette solution peut être la vôtre.
Nous devrions idéalement utiliser "file:/dev /./ urandom" après Java 5 comme chemin précédent pointera à nouveau vers/dev/random.
Bogue signalé: https://bugs.openjdk.Java.net/browse/JDK-6202721
Disclamer: Je ne suis lié à aucun fournisseur de produit ou produit ...
Si votre besoin est d'atteindre un niveau aléatoire de haute qualité, vous pouvez remplacer votre logiciel générateur de nombres aléatoires Linux par un matériel.
Certaines informations sont disponibles ici .
Cordialement
Thomas
Solution
Modifiez la configuration de votre application, afin que vous ce paramètre [ - Djava.security.egd = fichier:/dev /../ dev/urandom ] à côté de la commande Java:
Java - Djava.security.egd = fichier:/dev /../ dev/urandom [votre commande]
Nous avons rencontré ces erreurs par intermittence après la mise à niveau de 11g vers 12c et notre Java était sur 1.6.
Le correctif pour nous était de mettre à niveau Java et jdbc de 6 à 7
export Java_HOME='/usr/Java1.7'
export CLASSPATH=/u01/app/Oracle/product/12.1.0/dbhome_1/jdbc/libojdbc7.jar:$CLASSPATH
Plusieurs jours plus tard, la connexion toujours intermittente est réinitialisée.
Nous avons fini par supprimer tous les Java 7 ci-dessus. Java 6 était bien. Le problème a été résolu en l'ajoutant à notre utilisateur bash_profile).
Nos scripts groovy qui rencontraient l'erreur utilisaient/dev/random sur notre lot VM serveur. Ci-dessous forcé Java et groovy pour utiliser/dev/urandom.
export Java_OPTS = "$ Java_OPTS -Djava.security.egd = fichier: /// dev/urandom"
Votre exception dit tout "réinitialisation de la connexion". La connexion entre votre Java et le serveur db a été perdue, ce qui aurait pu se produire pour presque n'importe quelle raison (comme des problèmes de réseau). Le SQLRecoverableException signifie simplement que son récupérable , mais la cause principale est la réinitialisation de la connexion.