web-dev-qa-db-fra.com

Résolution d'un "problème de liaison de communication" avec JDBC et MySQL

J'essaie de me connecter au serveur MySQL local, mais le message d'erreur persiste.

Voici le code.

public class Connect {

    public static void main(String[] args) {
        Connection conn = null;

        try {
            String userName = "myUsername";
            String password = "myPassword";

            String url = "jdbc:mysql://localhost:3306/myDatabaseName";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(url, userName, password);
            System.out.println("Database connection established");
        } catch (Exception e) {
            System.err.println("Cannot connect to database server");
            System.err.println(e.getMessage());
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                    System.out.println("Database Connection Terminated");
                } catch (Exception e) {}
            }
        }
    }
}

et les erreurs:

Cannot connect to database server
Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:39)
        at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:27)
        at Java.lang.reflect.Constructor.newInstance(Constructor.Java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.Java:411)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.Java:1116)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.Java:344)
        at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.Java:2333)
        at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.Java:2370)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.Java:2154)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.Java:792)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.Java:47)
        at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at Sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.Java:39)
        at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:27)
        at Java.lang.reflect.Constructor.newInstance(Constructor.Java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.Java:411)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.Java:381)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.Java:305)
        at Java.sql.DriverManager.getConnection(DriverManager.Java:582)
        at Java.sql.DriverManager.getConnection(DriverManager.Java:185)
        at Connect.main(Connect.Java:16)
    Caused by: Java.net.ConnectException: Connection refused
        at Java.net.PlainSocketImpl.socketConnect(Native Method)
        at Java.net.PlainSocketImpl.doConnect(PlainSocketImpl.Java:351)
        at Java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.Java:213)
        at Java.net.PlainSocketImpl.connect(PlainSocketImpl.Java:200)
        at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:366)
        at Java.net.Socket.connect(Socket.Java:529)
        at Java.net.Socket.connect(Socket.Java:478)
        at Java.net.Socket.<init>(Socket.Java:375)
        at Java.net.Socket.<init>(Socket.Java:218)
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.Java:257)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.Java:294)
        ... 15 more

J'ai défini le classpath, en m'assurant que l'option ignorer le réseau a été commentée dans my.cnf.

La version de Java est 1.2.0_26 (64 bits) mysql 5.5.14 connecteur mysql 5.1.17

Je me suis assuré que l'utilisateur avait accès à ma base de données.

183
Anthony

J'ai eu le même problème dans deux de mes programmes. Mon erreur était la suivante:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

J'ai passé plusieurs jours à résoudre ce problème. J'ai testé de nombreuses approches mentionnées dans différents sites Web, mais aucune d'entre elles n'a fonctionné. Finalement, j'ai changé mon code et découvert quel était le problème. Je vais essayer de vous parler d’approches différentes et de les résumer ici .

Alors que je cherchais Internet pour trouver la solution à cette erreur, j’ai compris que de nombreuses solutions fonctionnaient pour au moins une personne, mais d’autres affirmaient que cela ne fonctionnait pas pour elles. ! Pourquoi existe-t-il plusieurs approches à cette erreur? Il semble que cette erreur peut se produire généralement en cas de problème de connexion au serveur . Le problème est peut-être dû à une chaîne de requête incorrecte ou à un trop grand nombre de connexions à la base de données.

Donc, je vous suggère d'essayer toutes les solutions une par une et n'abandonnez pas!

Voici les solutions que j'ai trouvées sur Internet et pour chacune d'entre elles, il y a au moins une personne à qui son problème a été résolu avec cette solution.

Conseil: pour les solutions dont vous avez besoin pour modifier les paramètres MySQL, vous pouvez vous référer aux fichiers suivants:

  • Linux: /etc/mysql/my.cnf ou /etc/my.cnf (selon la distribution Linux et le paquet MySQL utilisés)

  • Windows: C: ** ProgramData **\MySQL\MySQL Server 5.6\my.ini (remarquez qu'il s'agit de ProgramData et non de Program Files)

Voici les solutions:

  • modification de l'attribut "bind-address"

Décommentez l'attribut "bind-address" ou remplacez-le par l'une des adresses IP suivantes:

bind-address = "127.0.0.1"

ou

bind-address = "0.0.0.0"

  • en commentant "skip-networking"

S'il y a une ligne "skip-networking" dans votre fichier de configuration MySQL, commentez-la en ajoutant le signe "#" au début de cette ligne.

  • changez "wait_timeout" et "interactive_timeout"

Ajoutez ces lignes au fichier de configuration MySQL:

wait_timeout = nombre

interactive_timeout = nombre

connect_timeout = nombre

  • Assurez-vous que Java ne traduit pas 'localhost' en [::: 1] au lieu de [127.0.0.1]

Depuis que MySQL reconnaît 127.0.0.1 (IPv4) mais pas ::: 1 (IPv6)

Cela pourrait être évité en utilisant l'une des deux approches suivantes:

Option n ° 1: dans la chaîne de connexion, utilisez 127.0.0.1 au lieu de localhost pour éviter que localhost ne soit traduit en ::: 1

Option n ° 2: exécutez Java avec l'option -Djava.net.preferIPv4Stack = true pour forcer Java à utiliser IPv4 au lieu de IPv6. Sous Linux, cela pourrait également être réalisé en exécutant (ou en le plaçant dans/etc/profile:

export _Java_OPTIONS="-Djava.net.preferIPv4Stack=true"
  • vérifier les paramètres de proxy du système d'exploitation, les pare-feu et les programmes anti-virus

Assurez-vous que le logiciel pare-feu ou antivirus ne bloque pas le service MySQL.

Arrêtez iptables temporairement sur Linux. Si les iptables sont mal configurés, ils peuvent autoriser l’envoi de paquets TCP sur le port mysql, mais empêcher les paquets TCP de revenir sur la même connexion.

# Redhat enterprise and CentOS
systemctl stop iptables.service
# Other linux distros
service iptables stop

Arrêtez le logiciel anti-virus sur Windows.

  • modifier la chaîne de connexion

Vérifiez votre chaîne de requête. votre chaîne de connexion devrait ressembler à ceci:

dbName = "my_database";
dbUserName = "root";
dbPassword = "";
String connectionString = "jdbc:mysql://localhost/" + dbName + "?user=" + dbUserName + "&password=" + dbPassword + "&useUnicode=true&characterEncoding=UTF-8";

Assurez-vous de ne pas avoir d'espaces dans votre chaîne. Toute la chaîne de connexion doit être continue sans aucun espace.

Essayez de remplacer "localhost" par l'adresse de bouclage 127.0.0.1. Essayez également d’ajouter un numéro de port à votre chaîne de connexion, par exemple:

String connectionString = "jdbc:mysql://localhost:3306/my_database?user=root&password=Pass&useUnicode=true&characterEncoding=UTF-8";

Le port par défaut pour MySQL est 3306.

N'oubliez pas de changer le nom d'utilisateur et mot de passe pour le nom d'utilisateur et mot de passe de votre serveur MySQL.

  • mettez à jour votre fichier de bibliothèque de pilotes JDK
  • Testez différents JDK et JRE (tels que JDK 6 et 7)
  • ne change pas max_allowed_packet

" max_allowed_packet " est une variable dans le fichier de configuration MySQL qui indique la taille maximale des paquets, pas le nombre maximal de paquets. Donc, cela ne va pas aider à résoudre cette erreur.

  • changer la sécurité de Tomcat

remplacez Tomcat6_SECURITY = yes par Tomcat6_SECURITY = no

  • utilise la propriété validationQuery

utilisez validationQuery = "select now ()" pour vous assurer que chaque requête a des réponses

  • AutoReconnect

Ajoutez ce code à votre chaîne de connexion:

&autoReconnect=true&failOverReadOnly=false&maxReconnects=10

Bien qu'aucune de ces solutions n'ait fonctionné pour moi, je vous suggère de les essayer. Parce que certaines personnes ont résolu leur problème en suivant ces étapes.

Mais qu'est-ce qui a résolu mon problème?

Mon problème était que j'avais beaucoup de SELECT sur la base de données. À chaque fois, je créais une connexion et la fermais. Bien que je fermais la connexion à chaque fois, mais le système a été confronté à de nombreuses connexions et m'a donné cette erreur. Ce que j'ai fait est de définir ma variable de connexion en tant que variable publique (ou privée) pour l'ensemble de la classe et de l'initialiser dans le constructeur. vient d'utiliser cette connexion. Cela a résolu mon problème et a également augmenté ma vitesse de façon spectaculaire.

Conclusion

Il n'y a pas de moyen simple et unique pour résoudre ce problème. Je vous suggère de réfléchir à votre propre situation et de choisir les solutions ci-dessus. Si vous prenez cette erreur au début du programme et que vous ne parvenez pas du tout à vous connecter à la base de données, vous risquez d'avoir un problème avec votre chaîne de connexion. Mais si vous prenez cette erreur après plusieurs interactions réussies avec la base de données, le problème peut être lié au nombre de connexions et vous pouvez penser à modifier "wait_timeout" et d'autres paramètres MySQL, ou à réécrire votre code de manière à réduire le nombre de connexions.

358
Soheil

Si vous utilisez MAMP PRO, la solution facile, que je souhaiterais vraiment réaliser avant de commencer à chercher sur Internet pendant des jours pour essayer de comprendre cela. C'est vraiment aussi simple que ça ...

Il vous suffit de cliquer sur "Autoriser l'accès réseau à MySQL" dans l'onglet MAMP MySQL.

Vraiment, c'est tout.

Oh, et vous devrez TOUJOURS changer votre adresse de lien en 0.0.0.0 ou 127.0.0.1 comme indiqué dans les articles ci-dessus, mais le fait de ne cocher que cette case résoudra probablement vos problèmes si vous êtes un utilisateur de MAMP.

12
Peter John Joseph

Définir le bind-address sur l’IP du réseau du serveur au lieu de l’hôte par défaut localhost, et la définition des privilèges sur mon utilisateur a fonctionné pour moi.

mon.cnf:

bind-address = 192.168.123.456

Console MySql:

GRANT ALL PRIVILEGES ON dbname.* to username@'%' IDENTIFIED BY 'password';
5
Kevin Lawrence

Dans mon cas,

  1. Changez la configuration mysql de la machine distante à /etc/mysql/my.cnf: remplacez bind-address = 127.0.0.1 par #bind-address = 127.0.0.1

  2. Sur la machine distante, changez les permissions de l'utilisateur mysql avec GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password';

  3. IMPORTANT: redémarrez mysql sur la machine distante: Sudo /etc/init.d/mysql restart

4
cindyxiaoxiaoli

Dans mon cas, il s’agissait d’un délai d’inactivité qui a entraîné l’abandon de la connexion sur le serveur. La connexion a été maintenue ouverte, mais n'a pas été utilisée pendant une longue période. Ensuite, un redémarrage client fonctionne, alors que je pense qu'une reconnexion fonctionnera également.

Une solution pas mal n'est d'avoir un démon/service pour envoyer une requête ping à la connexion de temps en temps.

3
fuoco

Comme l'indique la réponse détaillée ci-dessus, cette erreur peut avoir plusieurs causes.

J'ai eu ce problème également. Ma configuration était Mac OSX 10.8, en utilisant une VirtualBox gérée par Vagrant VM d’Ubuntu 12.04, avec MySQL 5.5.34.

J'avais correctement configuré la redirection de port dans le fichier de configuration Vagrant. Je pourrais téléphoner à l'instance MySQL à la fois depuis mon Mac et depuis la machine virtuelle. Je savais donc que le démon MySQL était en cours d'exécution et accessible. Mais lorsque j'ai essayé de me connecter via JDBC, j'ai eu l'erreur "Échec de la liaison de communication".

Dans mon cas, le problème a été résolu en modifiant le fichier /etc/mysql/my.cnf. Plus précisément, j'ai commenté la ligne "# bind-address = 127.0.0.1".

3
devdanke

Dans mon cas (je suis un noob), je testais les servlets qui établissent une connexion de base de données avec MySQL. L’une des exceptions est celle mentionnée ci-dessus.

Cela m'a fait tourner la tête pendant quelques secondes, mais je me suis rendu compte que c'était parce que je n'ai pas démarré mon serveur MySQL dans localhost.
Après le démarrage du serveur, le problème a été résolu.

Donc, vérifiez si le serveur MySQL fonctionne correctement.

3
Barun

Je viens de faire face au même problème. Cela est dû au fait que le démon MySQL était lié à l'adresse IP de la machine, indispensable pour établir une connexion avec un utilisateur disposant de l'autorisation de se connecter @votre_machine. Dans ce cas, l'utilisateur doit avoir l'autorisation de se connecter USER_NAME @ MACHINE_NAME_OR_IP

Je voulais un accès à distance à ma machine, alors j’ai changé dans my.cnf à partir de

bind-address = MY_IP_ADDRESS

À

bind-address = 0.0.0.0

Ce qui permettra à un utilisateur de localhost ET même à l'extérieur (dans mon cas) de se connecter à l'instance. Les deux autorisations ci-dessous fonctionneront si vous liez MySQL à 0.0.0.0:

USER_NAME@MACHINE_NAME_OR_IP

USER_NAME@localhost
3
Renann

Si vous rencontrez des problèmes avec un ensemble de conteneurs Docker, assurez-vous de ne pas seulement EXPOSE le port 3306, mais également de mapper le port de l'extérieur conteneur -p 3306:3306. Pour docker-compose.yml:

version: '2'

services:
    mdb:
        image: mariadb:10.1
        ports:
            - "3306:3306"
        …
2
kaiser

Pour moi, la solution a été de changer dans le fichier de configuration du serveur mysql le paramètre bind-address = "127.0.0.1" ou bind-address = "x.x.x.x" en bind-address = "0.0.0.0". Merci.

1
jpenaab

Accédez aux services Windows dans le panneau de configuration et démarrez le service MySQL. Pour moi cela a fonctionné. Lorsque je travaillais sur un projet Java EE, le message d'erreur "Échec de la liaison de communication" s'est produit. J'ai redémarré mon système et puis cela a fonctionné.

Après cela, j'ai encore eu la même erreur même après avoir redémarré mon système. Ensuite, j’ai essayé d’ouvrir la console de ligne de commande MySQL et de me connecter à l’ordinateur root, mais cela m’a donné une erreur.

Enfin, lorsque j'ai lancé le service MySQL à partir de services Windows, cela a fonctionné.

0
tinku

Je sais que c'est un vieux fil, mais j'ai essayé de nombreuses choses et résolu mon problème en utilisant les moyens suivants.

Je développe une application multiplateforme sous Windows, mais destinée à être utilisée sur des serveurs Linux et Windows.

Une base de données MySQL appelée "jtm" installée sur les deux systèmes. Pour une raison quelconque, dans mon code, le nom de la base de données était "JTM". Sous Windows, cela a bien fonctionné. En fait, sur plusieurs systèmes Windows, il a volé.

Sur Ubuntu, j'ai eu l'erreur ci-dessus à maintes reprises. Je l'ai testé avec le cas correct dans le code "jtm" et cela fonctionne un régal.

Linux est évidemment beaucoup moins tolérant en ce qui concerne la sensibilité à la casse (à juste titre), alors que Windows tient compte de tout.

Je me sens un peu bête maintenant mais vérifiez tout. Le message d'erreur n'est pas le meilleur, mais il semble être réparable si vous persévérez et faites les choses correctement.

0
thonnor

Dans l'option phpstorm + vagrant autoReconnect du pilote aide.

0
gaRex

Si vous utilisez la mise en veille prolongée, cette erreur peut être due au fait de garder ouvert un objet de session plus de temps que wait_timeout

J'ai documenté un cas dans ici pour ceux qui sont intéressés.

0
Raul Luna

C'est principalement à cause de la faible connexion entre le client mysql et le serveur mysql distant.

Dans mon cas, c'est à cause d'une connexion VPN irrégulière.

0
Ankit Singhal

Je viens de redémarrer MySQL (en suivant un conseil: https://stackoverflow.com/a/142388 ) et le problème a été résolu

J'ai eu le même problème sur MacOS (10.10.2) et MySql (5.6.21) installés via homebrew.

La confusion était que l'une de mes applications connectée à la base de données était correcte et l'autre pas.

Après avoir essayé beaucoup de choses sur l'application qui a lancé l'exception com.mysql.jdbc.CommunicationsException comme suggéré par la réponse acceptée à cette question en vain, j'ai été surpris de constater que le redémarrage de MySQL fonctionnait.

La cause de mon problème aurait pu être la suivante, comme suggéré dans la réponse au lien susmentionné:

Utilisez-vous un pool de connexion? Si oui, essayez de redémarrer le serveur. Il est probable que peu de connexions dans votre pool de connexions sont à l'état fermé.

0
dulon

J'ai fait face à ce problème aussi.

Comme suggéré par Soheil, je suis allé dans le fichier php.ini au chemin C:\windows\php.ini, puis j'ai révisé le numéro de port dans ce fichier.

c'est sur la ligne mysqli.default_port = ..........

Donc, je l'ai changé dans mon application Java comme dans le fichier php.ini, maintenant cela fonctionne bien avec moi.

0
PHPFan

Je rencontrais un problème similaire et la solution à mon cas était

  1. changement de bind-address = 0.0.0.0 de 127.0.0.1
  2. changer l'URL de localhost en localhost: 3306

ce que j’ai pensé, c’est que nous ne devrions jamais abandonner. J’ai essayé toutes les options de cet article et d’autres forums également… heureux que cela fonctionne @saurab

0
Saurab Dulal

j'ai trouvé la solution

puisque MySQL a besoin du Localhost pour fonctionner.

allez dans le fichier / etc/network/interfaces et assurez-vous que la configuration localhost est définie ici:

auto lo
iface lo inet loopback

MAINTENANT, REDÉMARREZ le sous-système Networking et les services MySQL:

Sudo /etc/init.d/networking restart

Sudo /etc/init.d/mysql restart

Essayez-le maintenant

0
Mahmoud Zalt

Après des années à avoir le même problème et aucune solution permanente, c'est ce qui a été résolu pour les 3 dernières semaines (ce qui est un record en termes de fonctionnement sans erreur)

set global wait_timeout = 3600;
set global interactive_timeout = 230400;

N'oubliez pas de rendre ce permanent si cela fonctionne pour vous.

0
itpp13

Avait le même. Supprimer le port a aidé dans mon cas, donc je l'ai laissé comme jdbc: mysql: // localhost /

0
user2180110

Cela arrive (dans mon cas) quand il n'y a pas assez de mémoire pour MySQL. Un redémarrage le corrige, mais si c'est le cas, considérez une nachine avec plus de mémoire, ou limitez la mémoire prise par jvms

0
Bozho

Pour Windows: - Dans le menu Démarrer, écrivez "Assistant de configuration d'instance de serveur MySql" et configurez votre instance de serveur mysql. J'espère que cela résoudra votre problème.

0
Himanshu Narang

La résolution fournie par Soheil a été couronnée de succès dans mon cas.

Pour clarifier, le seul changement que je devais faire était avec la configuration du serveur de MySQL;

bind-address = **INSERT-IP-HERE**

J'utilise un serveur MySQL externe pour mon application. Il s’agit d’une installation de base de Debian 7.5 avec MySQL Server 5.5 - configuration par défaut.

IMPORTANT:

Sauvegardez toujours l'original de tous les fichiers de configuration que vous pourriez modifier. Faites toujours attention lorsque vous devenez un super utilisateur.

Fichier

/etc/mysql/my.cnf

Ligne

bind-address        = 192.168.0.103 #127.0.0.1

Redémarrez votre service serveur MySQL:

/usr/sbin/service mysql restart

Comme vous pouvez le constater, j'ai simplement fourni l'adresse IP du réseau du serveur et commenté l'entrée par défaut. Veuillez noter que simplement copier et coller ma solution ne fonctionnera pas pour vous, sauf miracle, nos hôtes partagent la même adresse IP.

Merci @ Soheil

0
Captain Dusty