Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Rozwiązywanie problemu awarii łącza komunikacyjnego za pomocą JDBC i MySQL

Ten sam problem miałem w dwóch moich programach. Mój błąd był następujący:

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.

Spędziłem kilka dni, aby rozwiązać ten problem. Przetestowałem wiele podejść, o których wspomniano na różnych stronach internetowych, ale żadne z nich nie zadziałało. W końcu zmieniłem kod i dowiedziałem się, na czym polega problem. Postaram się opowiedzieć o różnych podejściach i podsumować je tutaj .

Kiedy szukałem w Internecie rozwiązania tego błędu, odkryłem, że istnieje wiele rozwiązań, które działały dla co najmniej jednej osoby, ale inni twierdzą, że to nie działa dla nich! dlaczego istnieje wiele sposobów rozwiązania tego błędu? Wygląda na to, że ten błąd może wystąpić ogólnie gdy jest problem z połączeniem z serwerem . Być może problem wynika z nieprawidłowego ciągu zapytania lub zbyt wielu połączeń z bazą danych.

Sugeruję więc wypróbowanie wszystkich rozwiązań jeden po drugim i nie poddawaj się!

Oto rozwiązania, które znalazłem w Internecie i dla każdego z nich jest przynajmniej osoba, której problem został rozwiązany za pomocą tego rozwiązania.

Wskazówka:rozwiązania, których potrzebujesz, aby zmienić ustawienia MySQL, możesz znaleźć w następujących plikach:

  • Linux:/etc/mysql/my.cnf lub /etc/my.cnf (w zależności od używanej dystrybucji Linuksa i pakietu MySQL)

  • Windows:C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini (Zauważ, że to ProgramData, a nie Program Files)

Oto rozwiązania:

  • zmiana bind-address atrybut:

    Usuń komentarz bind-address atrybut lub zmień go na jeden z następujących adresów IP:

     bind-address="127.0.0.1"
    

    lub

     bind-address="0.0.0.0"
    
  • komentowanie „pomijania sieci”

    Jeśli istnieje skip-networking w pliku konfiguracyjnym MySQL, skomentuj, dodając # znak na początku tej linii.

  • zmień „wait_timeout” i „interactive_timeout”

    Dodaj te wiersze do pliku konfiguracyjnego MySQL:

    [wait_timeout][1] = *number*
    
    interactive_timeout = *number*
    
    connect_timeout = *number*
    
  • Upewnij się, że Java nie tłumaczy „localhost” na [:::1] zamiast [127.0.0.1]

    Ponieważ MySQL rozpoznaje 127.0.0.1 (IPv4 ) ale nie :::1 (IPv6 )

    Można tego uniknąć, stosując jedno z dwóch podejść:

    1. W ciągu połączenia użyj 127.0.0.1 zamiast localhost aby uniknąć localhost tłumaczone na :::1

    2. Uruchom java z opcją -Djava.net.preferIPv4Stack=true aby zmusić java do używania IPv4 zamiast IPv6 . W systemie Linux można to również osiągnąć, uruchamiając (lub umieszczając go w /etc/profile :

       export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"
      
  • sprawdź ustawienia proxy systemu operacyjnego, zapory sieciowe i programy antywirusowe

    Upewnij się, że zapora lub oprogramowanie antywirusowe nie blokuje usługi MySQL.

    Zatrzymaj tymczasowo iptables na Linuksie. Jeśli iptables są źle skonfigurowane, mogą zezwalać na wysyłanie pakietów tcp do portu mysql, ale blokują powrót pakietów tcp na tym samym połączeniu.

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

    Zatrzymaj oprogramowanie antywirusowe w systemie Windows.

  • zmień parametry połączenia

    Sprawdź ciąg zapytania. twoje parametry połączenia powinny wyglądać mniej więcej tak:

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

Upewnij się, że w ciągu nie ma spacji. Cały ciąg połączenia powinien być kontynuowany bez żadnych znaków spacji.

Spróbuj zastąpić „localhost” adresem sprzężenia zwrotnego 127.0.0.1. Spróbuj także dodać numer portu do ciągu połączenia, na przykład:

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

Zazwyczaj domyślny port dla MySQL to 3306.

Nie zapomnij zmienić nazwy użytkownika i hasła na nazwę użytkownika i hasło do serwera MySQL.

  • zaktualizuj plik biblioteki sterownika JDK
  • przetestuj różne JDK i JRE (takie jak JDK 6 i 7)
  • nie zmieniaj max_allowed_packet

max_allowed_packet " to zmienna w pliku konfiguracyjnym MySQL, która wskazuje maksymalny rozmiar pakietu, a nie maksymalną liczbę pakietów. Nie pomoże więc rozwiązać tego błędu.

  • zmień zabezpieczenia tomcat

zmień TOMCAT6_SECURITY=tak na TOMCAT6_SECURITY=nie

  • użyj właściwości validationQuery

użyj validationQuery="select now()", aby upewnić się, że każde zapytanie ma odpowiedzi

  • Automatyczne ponowne łączenie

Dodaj ten kod do ciągu połączenia:

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

Chociaż żadne z tych rozwiązań nie zadziałało dla mnie, proponuję je wypróbować. Ponieważ są ludzie, którzy rozwiązali swój problem, wykonując te kroki.

Ale co rozwiązało mój problem?

Mój problem polegał na tym, że miałem wiele SELECTów w bazie danych. Za każdym razem tworzyłem połączenie, a następnie je zamykałem. Co prawda za każdym razem zamykałem połączenie, ale system napotkał wiele połączeń i dał mi ten błąd. Zrobiłem to, że zdefiniowałem swoją zmienną połączenia jako publiczną (lub prywatną) zmienną dla całej klasy i zainicjowałem ją w konstruktorze. Potem za każdym razem, gdy po prostu korzystałem z tego połączenia. To rozwiązało mój problem, a także znacznie zwiększyło moją prędkość.

#Wniosek#Nie ma prostego i unikalnego sposobu na rozwiązanie tego problemu. Proponuję zastanowić się nad własną sytuacją i wybrać powyższe rozwiązania. Jeśli weźmiesz ten błąd na początku programu i nie możesz w ogóle połączyć się z bazą danych, możesz mieć problem z ciągiem połączenia. Ale jeśli popełnisz ten błąd po kilku udanych interakcjach z bazą danych, problem może dotyczyć liczby połączeń i możesz pomyśleć o zmianie „wait_timeout” i innych ustawieniach MySQL lub przepisać kod w taki sposób, aby zmniejszyć liczbę połączeń.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JSON_OBJECT() – Utwórz obiekt JSON z listy par klucz/wartość w MySQL

  2. Przekroczono limit czasu oczekiwania blokady; spróbuj zrestartować transakcję dla „zablokowanej tabeli Mysql?

  3. JSON_CONTAINS_PATH() Przykłady w MySQL

  4. MySQL:@zmienna a zmienna. Co za różnica?

  5. Skonfiguruj replikację bazy danych Master-Master MySQL