MySQLに対してクエリを実行するWebアプリ(Tomcat / Hibernate / DBCP 1.4)があります。これは、特定の負荷、たとえば1秒間に50クエリで正常に機能します。同じ中程度の負荷をHAProxy経由でルーティングすると(まだ単一のデータベースを使用しているだけです)、500クエリごとに1つ、失敗する可能性があります。私のアプリのレポート:
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 196,898 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago.
at sun.reflect.GeneratedConstructorAccessor210.newInstance(Unknown Source)
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:1117)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3567)
...
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3017)
...
一方、HAProxyログには次のような多くのエントリが表示されます。
27] mysql mysql/db03 0/0/34605 2364382 cD 3/3/3/3/0 0/0
Oct 15 15:43:12 localhost haproxy[3141]: 127.0.0.1:35500 [15/Oct/2012:15:42:50.0
「cD」は明らかにクライアントのタイムアウトの状態を示しています。したがって、私のWebアプリケーションはHAProxyが新しい接続の受け入れを拒否していると言っていますが、HAProxyは私のWebアプリがデータを受け入れていないと言っています。
多くの異なるパラメーター値を試したため、基本的に同じ結果が得られたため、HAProxy構成を含めていません。特に、グローバルセクションとサーバーセクションの両方でmaxconnを高い値と低い値の両方に設定しました。統計で常に発生するのは、最大セッションが約7以下に上昇することです。JDBCプールのサイズも大きいです。
通常、JDBCプールとHAProxyプールを一緒に使用しても大丈夫ですか?人々は以前にこの種の問題に遭遇したことがありますか?
私はこれを解決する方法について考えています。それは、すべてのクエリの前に「検証クエリ」を送信することです。しかし、そこには一定のオーバーヘッドがあり、MySQLに直接アクセスしたときにWebアプリが成功する理由を知りたいのですが、HAProxyを経由すると接続が切断されます。
どうすればさらにデバッグして、単なる「cD」よりも多くの情報を取得できますか?HAProxyをデバッグモードで実行しようとしましたが、それ以上何も表示されないようです。