Nie można połączyć się z mysql przez złącze JDBC przez Tomcat lub zewnętrznie

17

Zainstalowałem standardową instalację mysql 5.5 i chociaż mogę połączyć się z usługą mysql za pomocą komendy mysql, a usługa wydaje się być uruchomiona, nie mogę się z nią połączyć przez spring + tomcat lub z zewnętrznego złącza jdbc.

Używam następującego adresu URL:

jdbc:mysql://myserver.com:myport/mydb

z prawidłową nazwą użytkownika / hasłem, ale otrzymuję następujący komunikat:

server.com: 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 kocur rzuca:

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.
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

Co wydaje się być takim samym problemem, jak gdybym próbował połączyć się zewnętrznie.

Stefan Kendall
źródło
Napotkałem ten problem, próbując połączyć się przez java z moją bazą danych mysql, która działa na innym serwerze w mojej sieci LAN. podczas wykonywania tego samego programu Java na serwerze, na którym działa mysql, łączył się bez problemów. z zewnętrznego komputera mogłem połączyć się z bazą danych mysql na przykład za pomocą SQLYog (chociaż najpierw musiałem zmienić plik my.cnf, aby utworzyć powiązanie na 0.0.0.0 zamiast na 127.0.0.1). Odpowiedź Bodena i komentarz dotyczący zmiany złącza JDBC wskazały mi właściwy kierunek. Zmieniłem złącze JDBC na najnowszą wersję i nagle zadziałało!
user2380870

Odpowiedzi:

18

Może się to zdarzyć z różnych powodów. Właśnie widziałem to kilka tygodni temu, ale nie pamiętam, jaka była poprawka dla mnie.

1) Sprawdź, czy adres, z którym związany jest mysql, jest prawdopodobnie 127.0.0.1 (tylko), który moim zdaniem jest domyślny (przynajmniej na standardowym serwerze Ubuntu). Będziesz musiał skomentować parametr bind-address w my.cnf, aby powiązać ze wszystkimi dostępnymi adresami (nie możesz wybrać wielu, to jeden lub wszystkie).

2) Jeśli jest powiązany z 127.0.0.1 i nie można połączyć się za pomocą „localhost”, upewnij się, że nie jest on przetwarzany na adres localhost IPv6 zamiast IPv4. (lub po prostu użyj adresu IP)

3) Sprawdź dwukrotnie i potrójnie port, na którym nasłuchuje mysql.

4) Upewnij się, że używasz odpowiedniego złącza JDBC dla swojego JDK.

5) Upewnij się, że nie robisz czegoś naprawdę głupiego, jak uruchamianie mysql z --skip-networking.

Myślę, że moja pierwsza sugestia jest najbardziej obiecująca ... tak naprawdę myślę, że właśnie tam ją ostatnio widziałem ... Próbowałem połączyć się zdalnie z mysql (także na Ubuntu 8.04).

Boden
źródło
Żeby dodać moje 2 centy, 4. działało dla mnie. Dzięki!
Janis Peisenieks
1
w odniesieniu do „Będziesz musiał skomentować parametr bind-address w my.cnf, aby powiązać ze wszystkimi dostępnymi adresami”, domyślnie jest teraz nasłuchiwany tylko na localhost, więc może być konieczne użycie wiersza „bind-address = 0.0. 0.0 "w obrębie [mysqld].
Palo,
13

Miałem ten sam problem 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ędzam kilka dni, aby rozwiązać ten problem. Przetestowałem wiele podejść wymienionych na różnych stronach internetowych, ale żadne z nich nie działało. W końcu zmieniłem kod i dowiedziałem się, na czym polega problem. Spróbuję opowiedzieć ci o różnych podejściach i podsumuję je tutaj .

Gdy szukałem Internetu w celu znalezienia rozwiązania tego błędu, zorientowałem się, że istnieje wiele rozwiązań, które działały dla co najmniej jednej osoby, ale inni twierdzą, że to nie działa! dlaczego istnieje wiele podejść do tego błędu? Wygląda na to, że ten błąd może wystąpić na ogół, gdy występuje problem z połączeniem z serwerem . Być może problem wynika z niewłaściwego ciągu zapytania lub zbyt dużej liczby połączeń z bazą danych.

Proponuję więc wypróbować wszystkie rozwiązania 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.

punkt: W przypadku rozwiązań, które musisz zmienić ustawienia MySQL, możesz odnieść się do następujących kwestii:

  • Linux: /etc/my.cnf

  • Windows: D: \ Program Files \ mysql \ bin \ my.ini

Oto rozwiązania:

  • zmiana atrybutu „bind-address”

Odkomentuj atrybut „bind-address” lub zmień go na jeden z następujących Ips:

bind-address = "127.0.0.1"

lub

adres powiązania = „0.0.0.0”

  • komentując „skip-networking”

Jeśli w pliku konfiguracyjnym MySQL znajduje się wiersz „pomiń połączenie sieciowe”, dodaj komentarz, dodając znak „#” na początku tego wiersza.

  • zmień „wait_timeout” i „Interactive_timeout”

Dodaj następujące wiersze do pliku konfiguracyjnego MySQL:

wait_timeout = liczba

czas_interaktywny = liczba

connect_timeout = liczba

  • sprawdź ustawienia proxy systemu operacyjnego

Upewnij się, że Fire wall lub antywirusowe produkty miękkie nie blokują usługi MySQL.

  • zmień parametry połączenia

Sprawdź ciąg zapytania. ciąg połączenia powinien 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 łańcuchu nie ma spacji. Cały ciąg połączenia powinien być kontynuowany bez żadnych spacji.

Spróbuj zastąpić „localhost” swoim portem, np. 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";

Zwykle domyślnym portem dla MySQL jest 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 (jak JDK 6 i 7)
  • nie zmieniaj pakietu max_allowed_packet

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

  • zmień bezpieczeństwo tomcat

zmień TOMCAT6_SECURITY = tak na TOMCAT6_SECURITY = nie

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

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

  • Automatyczne wznawianie połączenia

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

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

Chociaż żadne z tych rozwiązań nie działało, proponuję je wypróbować. Ponieważ są ludzie, którzy rozwiązali problem z wykonaniem tych kroków.

Ale co rozwiązało mój problem? Mój problem polegał na tym, że miałem wiele SELECT w bazie danych. Za każdym razem tworzyłem połączenie, a następnie je zamykałem. Chociaż 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 zmienną połączenia jako zmienną publiczną (lub prywatną) dla całej klasy i zainicjowałem ją w konstruktorze. Potem za każdym razem korzystałem z tego połączenia. Rozwiązało to mój problem, a także znacznie zwiększyło moją prędkość.

Wniosek

Nie ma prostego i unikalnego sposobu rozwiązania tego problemu. Sugeruję, abyś pomyślał o swojej sytuacji i wybrał powyższe rozwiązania. Jeśli weźmiesz ten błąd na początku programu i w ogóle nie będziesz w stanie połączyć się z bazą danych, możesz mieć problem z ciągiem połączenia. Ale jeśli weźmiesz ten błąd po kilku udanych interakcjach z bazą danych, problem może wynikać z liczby połączeń i możesz pomyśleć o zmianie „wait_timeout” i innych ustawień MySQL lub przepisać kod, aby zmniejszyć liczbę połączeń.

Soheil
źródło
Też miałem ten problem! Ale początkowo zmieniłem mysql, aby nasłuchiwał portu 8888 zamiast 3306. SO, odpowiedź @ sohail pomogła, właśnie dodałem port 8888 do mojego URI i zadziałało!
To rozwiązało problem dla mnie! Z naszą konfiguracją Vagrant Homestead z jakiegoś powodu wiązało się ono z adresem podanym dla VM (10.0.2.15 w moim przypadku) zamiast localhost.
Lander
1

Jeśli prowadzisz instalację Linuksa, prawdopodobnie masz pakiet lokkit blokujący komunikację przychodzącą, z wyjątkiem SSH.

Zaloguj się jako root i uruchom polecenie lokkit z wiersza poleceń, wyłącz zaporę i SElinux i sprawdź, czy masz ten sam problem.

Sprawdź także, czy uprawnienia zostały ustawione poprawnie, aby wszystko mogło zapisywać w odpowiednich lokalizacjach.

Stephen Thompson
źródło
Używam Ubuntu 8.04. Prawdopodobnie powinienem o tym wspomnieć. Czy masz szczegółowe instrukcje dotyczące tej dystrybucji? Zaraz przejdę do wyszukiwarki Google, ale pomyślałem, że najpierw zapytam.
Stefan Kendall,
wyłączenie sudo ufw wyłączy Zaporę Ubuntu
Stephen Thompson
Zainstalowałem ufw i próbowałem włączyć port, ale żadnych kości.
Stefan Kendall,
ufw i iptables zostały już odinstalowane. Myślałem, że ufw to narzędzie do zarządzania, które trzeba było zainstalować osobno. Rzeczywiście, „iptables” nie daje takiego polecenia i wydaje się, że żadna usługa iptables nie działa.
Stefan Kendall,
Ok, w końcu często znajdowałem, że nie włączasz mysql do nasłuchiwania na interfejsie eth0, a często jest to tylko na interfejsie localhost. Spróbuj wykonać następujące czynności. Zmień jdbc: mysql: //myserver.com: myport / mydb na jdbc: mysql: // localhost: myport / mydb, jeśli to działa, musisz wykonać następujące dev.mysql.com/doc/refman/5.1/en/ can-not-connect-to-server.html
Stephen Thompson
1

Może to być również spowodowane niewłaściwymi ustawieniami proxy . Miałem ten problem podczas próby połączenia za pośrednictwem jdbc z instancją MySQL działającą w urządzeniu wirtualnym Parallels na moim komputerze Mac. Połączenie jdbc korzysta z ustawień sieciowych na poziomie systemu, a ponieważ byłem za serwerem proxy SOCKS, musiałem ustawić host MySql jako host bez serwera proxy (np. Na komputerze Mac możesz to skonfigurować w Ustawienia-> Sieć-> Zaawansowane- > Proxy i na koniec dodaj nazwę hosta lub adres IP w „Pomiń ustawienia proxy dla tych hostów i domen”).

Simone Bruno
źródło
1

MySQL Connector / J obsługuje tylko TCP / IP Java nie obsługuje połączeń z gniazdami domenowymi w systemie Unix

Jeśli MYSQL zostanie uruchomiony z flagą pomijania sieci lub jeśli MySQL działa za zaporą, wówczas opcja TCP / IP jest wyłączona. Aby Java nie mogła komunikować się z MySQL.

Sankar.lp.gym
źródło
0

przez prawie cały dzień miałem bardzo podobny problem i doprowadzało mnie to do szału! ale udało mi się znaleźć rozwiązanie i było to bardzo, bardzo proste, wystarczy /etc/init.d/tomcat6, aby zmienić TOMCAT6_SECURITY = tak na TOMCAT6_SECURITY = nie. to nie jest moje rozwiązanie, znalazłem to tutaj , jak widać, działam na Ubuntu, mam nadzieję, że to zadziała.


źródło
0

Miałem ten sam problem. Zmieniono właściwość „bind-address” w pliku /etc/mysql/my.cnf na 0.0.0.0 i działa. Odpowiednia linia w my.cnf wygląda następująco:

adres powiązania = 0.0.0.0

Zanim został ustawiony na zewnętrzny adres IP serwera, więc wyglądał mniej więcej tak:

adres powiązania = 196.152.4.145

Myślę, że kiedy jest ustawiony na zewnętrzny adres IP, a nie na pętlę localhost, serwer mysql jest podłączony do karty sieciowej i nie nasłuchuje połączeń z pętli lokalnej.


źródło
0

wypróbuj adres lokalny, aby powiązać adres w pliku my.cnf

Con con = null;

    try {
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://x62.xx8.x4x.x5:3306/mydb", "root", "root");
        try {
            System.out.println(con.getMetaData());
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } catch (ClassNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
ozgun bayrak
źródło