JDBC と MySQL による「通信リンク障害」の解決 [重複] 質問する

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

クラスパスを設定し、my.cnf で skip network オプションがコメントアウトされていることを確認しました。

Javaバージョンは1.2.0_26(64ビット)mysql 5.5.14、mysqlコネクタ5.1.17

ユーザーがデータベースにアクセスできることを確認しました。

ベストアンサー1

私の 2 つのプログラムで同じ問題が発生しました。エラーは次のとおりです。

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.

この問題を解決するのに数日かかりました。さまざまな Web サイトで言及されている多くのアプローチを試しましたが、どれもうまくいきませんでした。最終的に、コードを変更して問題が何であるかを突き止めました。さまざまなアプローチについて説明し、ここでまとめたいと思います。

このエラーの解決策をインターネットで探していたところ、少なくとも 1 人の人には効果があった解決策がたくさんあることがわかりましたが、他の人には効果がなかったという解決策もいくつかありました。 なぜこのエラーには多くのアプローチがあるのでしょうか。このエラーは、通常、サーバーへの接続に問題がある場合に発生するようです。おそらく、クエリ文字列が間違っているか、データベースへの接続が多すぎることが原因です。

したがって、すべての解決策を 1 つずつ試して、あきらめないことをお勧めします。

以下は私がインターネットで見つけた解決策です。それぞれの解決策で問題が解決した人が少なくとも 1 人います。

ヒント: MySQL 設定を変更するために必要な解決策については、次のファイルを参照してください。

  • Linux:/etc/mysql/my.cnfまたは/etc/my.cnf(使用する Linux ディストリビューションと MySQL パッケージによって異なります)

  • Windows: C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini(Program Files ではなく ProgramData であることに注意してください)

解決策は次のとおりです。

  • 属性の変更bind-address:

    属性のコメントを解除するbind-addressか、次のいずれかの IP に変更します。

     bind-address="127.0.0.1"
    

    または

     bind-address="0.0.0.0"
    
  • 「skip-networking」をコメントアウトする

    MySQL 設定ファイルに行がある場合は、その行の先頭に記号skip-networkingを追加してコメントにします。#

  • 「wait_timeout」と「interactive_timeout」を変更する

    MySQL 設定ファイルに次の行を追加します。

    [wait_timeout][1] = *number*
    
    interactive_timeout = *number*
    
    connect_timeout = *number*
    
  • Javaが 'localhost' を [127.0.0.1] ではなく [:::1] に変換していないことを確認してください。

    MySQLは127.0.0.1IPv4)を認識しますが:::1IPv6)は認識しません。

    これは、次の 2 つの方法のいずれかを使用することで回避できます。

    1. 接続文字列では、次のように変換されないように、 の127.0.0.1代わりに を使用してください。localhostlocalhost:::1

    2. javaを の代わりに-Djava.net.preferIPv4Stack=trueを使用するように強制するオプション付きで実行します。Linux では、 を実行する (または 内に配置) ことによってもこれを実現できます。IPv4IPv6/etc/profile

       export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"
      
  • オペレーティングシステムのプロキシ設定、ファイアウォール、ウイルス対策プログラムを確認する

    ファイアウォールまたはウイルス対策ソフトウェアが MySQL サービスをブロックしていないことを確認してください。

    Linux で iptables を一時的に停止します。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 および JRE (JDK 6 や 7 など) をテストする
  • max_allowed_pa​​cketを変更しない

最大許容パケット「」は、MySQL 構成ファイル内の変数であり、最大パケット数ではなく最大パケット サイズを示します。したがって、このエラーの解決には役立ちません。

  • tomcatのセキュリティを変更する

TOMCAT6_SECURITY=yes を TOMCAT6_SECURITY=no に変更します。

  • validationQueryプロパティを使用する

各クエリに応答があることを確認するには、validationQuery="select now()" を使用します。

  • 自動再接続

接続文字列に次のコードを追加します。

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

これらの解決策はどれも私には効果がありませんでしたが、試してみることをお勧めします。これらの手順に従うことで問題を解決した人もいるからです。

しかし、私の問題は何が解決したのでしょうか?

私の問題は、データベースに SELECT が多数あることでした。そのたびに接続を作成して閉じていました。そのたびに接続を閉じていたにもかかわらず、システムは多数の接続に直面し、そのエラーが発生していました。私が行ったのは、接続変数をクラス全体のパブリック (またはプライベート) 変数として定義し、コンストラクターで初期化することでした。その後、毎回その接続を使用しました。これで問題は解決し、速度も大幅に向上しました。

#結論# この問題を解決する簡単でユニークな方法はありません。自分の状況を考えて、上記の解決策を選択することをお勧めします。プログラムの開始時にこのエラーが発生し、データベースにまったく接続できない場合は、接続文字列に問題がある可能性があります。ただし、データベースとのやり取りが数回成功した後にこのエラーが発生する場合は、接続数に問題がある可能性があり、「wait_timeout」やその他の MySQL 設定を変更するか、接続数を減らすようにコードを書き直すことを検討してください。

おすすめ記事