Вопрос-ответ

Solving a "communications link failure" with JDBC and MySQL [duplicate]

Устранение "сбоя канала связи" с помощью JDBC и MySQL [дубликат]

Я пытаюсь подключиться к локальному серверу MySQL, но продолжаю получать сообщение об ошибке.

Вот код.

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) {}
}
}
}
}

и ошибки :

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

Я установил путь к классу, убедился, что в моем.cnf закомментирован параметр пропустить сеть.

версия java 1.2.0_26 (64-разрядная) mysql 5.5.14 mysql connector 5.1.17

Я убедился, что у пользователя есть доступ к моей базе данных.

Переведено автоматически
Ответ 1

У меня была такая же проблема в двух моих программах. Моя ошибка заключалась в следующем:

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.

I spent several days to solve this problem. I have tested many approaches that have been mentioned in different web sites, but non of them worked. Finally I changed my code and found out what was the problem. I'll try to tell you about different approaches and sum them up here.

While I was seeking the internet to find the solution for this error, I figured out that there are many solutions that worked for at least one person, but others say that it doesn't work for them! why there are many approaches to this error?
It seems this error can occur generally when there is a problem in connecting to the server. Maybe the problem is because of the wrong query string or too many connections to the database.

So I suggest you to try all the solutions one by one and don't give up!

Here are the solutions that I found on the internet and for each of them, there is at least on person who his problem has been solved with that solution.

Tip: For the solutions that you need to change the MySQL settings, you can refer to the following files:


  • Linux: /etc/mysql/my.cnf or /etc/my.cnf (depending on the Linux distribution and MySQL package used)



  • Windows: C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini (Notice it's ProgramData, not Program Files)



Here are the solutions:


  • changing bind-address attribute:


    Uncomment bind-address attribute or change it to one of the following IPs:


     bind-address="127.0.0.1"

    or


     bind-address="0.0.0.0"


  • commenting out "skip-networking"


    If there is a skip-networking line in your MySQL config file, make it comment by adding # sign at the beginning of that line.



  • change "wait_timeout" and "interactive_timeout"


    Add these lines to the MySQL config file:


    [wait_timeout][1] = *number*

    interactive_timeout = *number*

    connect_timeout = *number*


  • Make sure Java isn't translating 'localhost' to [:::1] instead of [127.0.0.1]


    Since MySQL recognizes 127.0.0.1 (IPv4) but not :::1 (IPv6)


    This could be avoided by using one of two approaches:



    1. In the connection string use 127.0.0.1 instead of localhost to avoid localhost being translated to :::1



    2. Run java with the option -Djava.net.preferIPv4Stack=true to force java to use IPv4 instead of IPv6. On Linux, this could also be achieved by running (or placing it inside /etc/profile:


       export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"




  • проверьте настройки прокси операционной системы, брандмауэры и антивирусные программы


    Убедитесь, что брандмауэр или антивирусное программное обеспечение не блокирует службу MySQL.


    Временно остановите iptables в Linux. Если iptables неправильно сконфигурированы, они могут разрешать отправку tcp-пакетов на порт mysql, но блокировать возврат tcp-пакетов по тому же соединению.


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

    Остановите антивирусное программное обеспечение в Windows.



  • измените строку подключения


    Проверьте строку вашего запроса. ваша строка подключения должна быть примерно такой:


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


Убедитесь, что в вашей строке нет пробелов. Вся строка подключения должна быть продолжена без каких-либо пробелов.

Попробуйте заменить "localhost" адресом обратной связи 127.0.0.1. Также попробуйте добавить номер порта в строку подключения, например:

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

Обычно порт по умолчанию для MySQL равен 3306.

Не забудьте сменить имя пользователя и пароль на имя пользователя и пароль вашего сервера MySQL.


  • обновите файл библиотеки драйверов JDK

  • протестируйте разные JDK и JRES (например, JDK 6 и 7)

  • не изменяйте max_allowed_packet

"max_allowed_packet" - это переменная в файле конфигурации MySQL, которая указывает максимальный размер пакета, а не максимальное количество пакетов. Таким образом, это не поможет устранить эту ошибку.


  • измените безопасность tomcat

измените TOMCAT6_SECURITY = да на TOMCAT6_SECURITY = нет


  • используйте свойство validationQuery

используйте validationQuery="select now()", чтобы убедиться, что на каждый запрос есть ответы


  • Автоматическое подключение

Добавьте этот код в строку подключения:

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

Хотя ни одно из этих решений у меня не сработало, я предлагаю вам попробовать их. Потому что есть люди, которые решили свою проблему, выполнив эти шаги.

Но что решило мою проблему?

Моя проблема заключалась в том, что у меня было много выборок в базе данных. Каждый раз, когда я создавал соединение, а затем закрывал его. Хотя я закрывал соединение каждый раз, но система сталкивалась со многими соединениями и выдавала мне эту ошибку. Что я сделал, так это определил свою переменную connection как общедоступную (или закрытую) переменную для всего класса и инициализировал ее в конструкторе. Затем каждый раз я просто использовал это соединение. Это решило мою проблему, а также значительно увеличило мою скорость.

#Вывод # Простого и уникального способа решения этой проблемы не существует. Я предлагаю вам подумать о вашей собственной ситуации и выбрать вышеуказанные решения. Если вы получаете эту ошибку в начале программы и вообще не можете подключиться к базе данных, возможно, у вас проблема со строкой подключения. Но если вы обнаружите эту ошибку после нескольких успешных взаимодействий с базой данных, проблема может быть в количестве подключений, и вы можете подумать об изменении "wait_timeout" и других настроек MySQL или переписать свой код, чтобы уменьшить количество подключений.

Ответ 2

Если вы используете MAMP PRO, это легко исправить, о чем я действительно жалею, что не понял до того, как начал целыми днями рыскать в Интернете, пытаясь разобраться в этом. Это действительно так просто...

Вам просто нужно нажать "Разрешить сетевой доступ к MySQL" на вкладке MAMP MySQL.

Действительно, вот и все.

О, и, ВОЗМОЖНО, вам все равно придется изменить свой адрес привязки либо на 0.0.0.0, либо на 127.0.0.1, как описано в сообщениях выше, но нажатие только на это поле, вероятно, решит ваши проблемы, если вы пользователь MAMP.

Ответ 3

Установка bind-address сетевого IP-адреса сервера вместо локального хоста по умолчанию и установка привилегий для моего пользователя сработали для меня.

my.cnf:

bind-address = 192.168.123.456

Консоль MySQL:

GRANT ALL PRIVILEGES ON dbname.* to username@'%' IDENTIFIED BY 'password';
Ответ 4

Если у вас возникли проблемы с набором контейнеров Docker, то убедитесь, что вы не только EXPOSE определяете порт 3306, но и сопоставляете порт извне контейнера -p 3306:3306. Для docker-compose.yml:

version: '2'

services:
mdb:
image: mariadb:10.1
ports:
- "3306:3306"

java mysql jdbc