web-dev-qa-db-ja.com

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がスキップネットワークオプションをコメントアウトさせたことを確認しました。

Javaのバージョンは1.2.0_26(64ビット)です。MySQL 5.5.14 MySQLコネクタ5.1.17

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

174
Anthony

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つずつ試してみて、giveめないでください。

ここに私がインターネットで見つけた解決策があり、それぞれについて、少なくとも彼の問題がその解決策で解決された人がいます。

ヒント:MySQL設定を変更する必要があるソリューションについては、次のファイルを参照できます。

  • Linux:/etc/mysql/my.cnfまたは/etc/my.cnf(使用しているLinuxディストリビューションとMySQLパッケージに応じて)

  • Windows:C:** ProgramData **\MySQL\MySQL Server 5.6\my.ini(プログラムファイルではなくProgramDataであることに注意してください)

ソリューションは次のとおりです。

  • 「バインドアドレス」属性の変更

「バインドアドレス」属性のコメントを解除するか、次の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 =number

interactive_timeout =number

connect_timeout =number

  • Javaが 'localhost'を[127.0.0.1]ではなく[::: 1]に変換していないことを確認してください

MySQLは127.0.0.1(IPv4)を認識しますが、::: 1(IPv6)は認識しないため

これは、次の2つのアプローチのいずれかを使用することで回避できます。

オプション#1:接続文字列でlocalhostではなく127.0.0.1を使用して、localhostが::: 1に変換されないようにします

オプション#2:Javaオプション-Djava.net.preferIPv4Stack = trueを実行して、JavaにIPv6の代わりにIPv4を使用させる。 Linuxでは、これを実行する(または/ 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を変更しない

" 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設定の変更を検討するか、接続数を減らす方法でコードを書き直すことができます。

358
Soheil

あなたがMAMP PROを使っているならば、私がこれを理解しようとしている何日もインターネットを検索し始める前に私が本当に実現したことを私が本当に望んでいる簡単な修正。それは本当にこれ簡単です...

MAMP MySQLタブから「MySQLへのネットワークアクセスを許可する」をクリックするだけです。

本当に、それだけです。

ああ、そしてあなたはまだ上の記事で概説したようにあなたのバインドアドレスを0.0.0.0か127.0.0.1のどちらかに変更しなければならないかもしれません、しかしあなたがMAMPユーザーであればそのボックスをクリックするだけであなたの問題を解決するでしょう。

12

bind-addressをlocalhostのデフォルトではなくサーバーのネットワークIPに設定し、そして私のユーザーに特権を設定することは私のために働いた。

my.cnf:

bind-address = 192.168.123.456

MySqlコンソール:

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

私の場合、

  1. リモートマシンのMySQL設定を/etc/mysql/my.cnfに変更します。bind-address = 127.0.0.1#bind-address = 127.0.0.1に変更します。

  2. リモートマシンで、GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password';を使用してmysqlユーザー権限を変更します。

  3. 重要:リモートマシン上でmysqlを再起動してください:Sudo /etc/init.d/mysql restart

4
cindyxiaoxiaoli

私の場合、それはアイドルタイムアウトであり、それが原因で接続がサーバー上でドロップされました。接続は開いたままになっていますが、長期間使用されていません。その後、クライアントの再起動が機能しますが、再接続も機能します。

悪くない解決策は、時々接続をpingするデーモン/サービスを持つことです。

3
fuoco

上記の詳細な回答が述べているように、このエラーはさまざまな原因で発生する可能性があります。

私もこの問題を抱えていました。私のセットアップはMac OSX 10.8で、MySQL 5.5.34でUbuntu 12.04のVagrant管理VirtualBox VMを使用しました。

Vagrant設定ファイルでポート転送を正しく設定しました。私は自分のMacからもVM内からもMySQLインスタンスにtelnetできました。それで私はMySQLデーモンが実行中で到達可能であることを知っていました。しかし、JDBCを介して接続しようとすると、「通信リンク障害」エラーが発生しました。

私の場合、問題は/etc/mysql/my.cnfファイルを編集することで解決しました。具体的には、 "#bind-address = 127.0.0.1"という行をコメントアウトしました。

3
devdanke

私はちょうど同じ問題に直面しました。これは、MySQLデーモンがマシンのIPにバインドされているために発生しました。これは、@ your_machineに接続する権限を持つユーザーと接続するために必要です。この場合、ユーザーはUSER_NAME @ MACHINE_NAME_OR_IPに接続する権限を持っている必要があります。

私は自分のマシンにリモートアクセスしたかったのでmy.cnfを

bind-address = MY_IP_ADDRESS

bind-address = 0.0.0.0

これにより、localhostからのユーザーも、(私の場合は)外部でもインスタンスに接続できます。 MySQLを0.0.0.0にバインドすると、以下の両方の権限が機能します。

USER_NAME@MACHINE_NAME_OR_IP

USER_NAME@localhost
3
Renann

私の場合は(私は新しい人です)、私はMySQLとのデータベース接続を行うサーブレットをテストしていました、そして例外の1つは上記のものです。

それは私の頭を数秒間揺れさせましたが、それは MySQLサーバーをlocalhostで起動していないからだと気づきました。
サーバーの起動後、問題は修正されました。

そのため、 MySQLサーバが正しく動作しているかどうかを確認してください

2
Barun

私にとっての解決策は、mysqlサーバーのconfファイルでパラメータbind-address = "127.0.0.1"またはbind-address = "x.x.x.x"をbind-address = "0.0.0.0"に変更することでした。ありがとう。

1
jpenaab

Dockerコンテナ のセットに問題がある場合は、EXPOSEをポート3306にするだけでなく、コンテナ-p 3306:3306の外側からポートをマップするようにしてください。 docker-compose.ymlの場合:

version: '2'

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

コントロールパネルのWindowsサービスに行き、MySQLサービスを開始してください。私にとってはうまくいった。 Java EEプロジェクトを行っていたときに、このエラー「通信リンク障害」が発生しました。私は自分のシステムを再起動した後、それはうまくいった。

その後、私は再び私のシステムを再起動した後でも同じエラーを受けました。それから私はMySQLコマンドラインコンソールを開いてrootでログインしようとしました、それでもそれは私にエラーを与えました。

最後に私がWindowsサービスからMySQLサービスを始めたとき、それはうまくいきました。

0
tinku

私はこれが古いスレッドであることを知っていますが、私は以下の手段を使用して多くのことを試みて私の問題を修正しました..

私はWindows上でクロスプラットフォームアプリケーションを開発していますが、LinuxおよびWindowsサーバー上で使用される予定です。

両方のシステムにインストールされた "jtm"というMySQLデータベース。何らかの理由で、私のコードでは私はデータベース名を "JTM"としました。 Windows上では問題なく動作しましたが、実際にはいくつかのWindowsシステムではうまくいっていました。

Ubuntuでは、何度も繰り返しエラーが出ました。私はコード "jtm"の正しいケースでそれをテストしました、そしてそれは御馳走を働きます。

Windowsは大文字と小文字を区別しますが、Linuxは大文字と小文字の区別について明らかに寛容ではありません。

私は今少し少々気分が悪くなりましたが、すべてを確認してください。エラーメッセージは最善ではありませんが、あなたが辛抱して物事を正しく行えば解決できるようです。

0
thonnor

Phpstorm + vagrant autoReconnectドライバオプションが役に立ちました。

0
gaRex

休止状態を使用している場合、このエラーはSessionオブジェクトをwait_timeoutより長い時間開いたままにしていることが原因である可能性があります。

興味のある人のために here でケースを文書化しました。

0
Raul Luna

これは主にmysqlクライアントとリモートmysqlサーバー間の接続が弱いためです。

私の場合、それは不安定なVPN接続が原因です。

0
Ankit Singhal

MySQLを再起動したところ(ここからヒントを得て: https://stackoverflow.com/a/14238800 )、問題が解決しました。

私は自作を介してインストールされたMacOS(10.10.2)とMySql(5.6.21)で同じ問題を抱えていました。

紛らわしいことに、私のアプリの一方はデータベースに正常に接続されていましたが、もう一方は接続されていませんでした。

この質問に対する広く認められた答えが示唆するように、例外com.mysql.jdbc.CommunicationsExceptionをスローした多くのことをアプリで試した後、MySQLの再起動がうまくいったことに驚きました。

前述のリンクの回答で示唆されているように、私の問題の原因は次のように考えられます。

接続プールを使用していますかインストールされている場合は、サーバーを再起動してください。おそらく、あなたのコネクションプール内のコネクションのうち、クローズ状態にあるものはほとんどありません。

0
dulon

私もこの問題に直面しました。

Soheilが示唆したように、私はパスC:\ windows\php.iniにあるphp.iniファイルに行き、そしてこのファイルのポート番号を修正しました。

mysqli.default_port = ..........という行にあります。

だから私はそれがphp.iniファイルにあるように私のJavaアプリでそれを変更しました、今それは私と一緒にうまく働きます。

0
PHPFan

私は同様の問題を経験していました、そして、私の場合の解決策は

  1. 127.0.0.1からbind-address = 0.0.0.0を変更
  2. uRLのローカルホストをローカルホストに変更する:3306

私が感じたことは私たちは決してあきらめてはいけないということです、私はこの記事からだけでなく、他のフォーラムからすべてのオプションを試してみました...それは幸せ@saurabは動作します

0
Saurab Dulal

解決策を見つけました

mySQLは動作するためにLocalhostを必要とするからです。

/etc/network/interfaces fileに移動し、そこにlocalhost設定があることを確認してください。

auto lo
iface lo inet loopback

ネットワークサブシステムとMySQLサービスを再起動します。

Sudo /etc/init.d/networking restart

Sudo /etc/init.d/mysql restart

やってみよう

0
Mahmoud Zalt

同じ問題を抱え、恒久的な解決策が何年もなかった後、これは過去3週間で解決したものです(これはエラーのない操作に関しては記録です)。

グローバルwait_timeout = 3600を設定します。
global interactive_timeout = 230400を設定します。

それがあなたのために働くならば、これを永久にすることを忘れないでください。

0
itpp13

同じでした。私の場合はportを削除するのが助けになったので、jdbc:mysql:// localhost /のままにしました。

0
user2180110

MySQL用に十分なメモリがない場合に起こります(私の場合)。再起動すると解決しますが、それでも問題が解決しない場合は、より多くのメモリを搭載したマシンを使用するか、jvmsが使用するメモリを制限してください。

0
Bozho

Windowsの場合: - [スタート]メニューの[MySqlserverインスタンス設定ウィザード]に移動して、mysqlサーバーインスタンスを再設定します。それがあなたの問題を解決することを願っています。

0
Himanshu Narang

私の場合、Soheilによる解決は成功しました。

明確にするために、私がしなければならなかった唯一の変更はMySQLのサーバー構成によるものでした。

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

私は自分のアプリケーションに外部MySQLサーバーを使用しています。これはMySQL Server 5.5を使った基本的なDebian 7.5インストールです - デフォルト設定。

重要:

常にあなたが変更することができるすべての設定ファイルのオリジナルをバックアップしてください。スーパーユーザーとして昇格したときは常に注意してください。

ファイル

/etc/mysql/my.cnf

ライン

bind-address        = 192.168.0.103 #127.0.0.1

MySQL Serverサービスを再起動します。

/usr/sbin/service mysql restart

ご覧のとおり、サーバーのネットワークIPアドレスを入力して、デフォルトのエントリをコメントアウトしています。奇妙なことに私たちのホストが同じIPアドレスを共有しない限り、単に私の解決策をコピーして貼り付けるだけではうまくいかないことに注意してください。

ありがとう@ Soheil

0
Captain Dusty