4

我有一个针对 MySQL 运行查询的 webapp (Tomcat/Hibernate/DBCP 1.4),这适用于特定负载,例如每秒 50 个查询。当我通过 HAProxy 路由相同的中等负载(仍然只使用一个数据库)时,我遇到了失败,可能每 500 个查询就有一个失败。我的应用报告:

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”显然表示客户端超时状态。因此,虽然我的 webapp 说 HAProxy 拒绝接受新连接,但 HAProxy 说我的 webapp 不接受返回数据。

我不包括我的 HAProxy 配置,因为我尝试了许多不同的参数值,结果基本相同。特别是,我在全局和服务器部分都将 maxconn 设置为高值和低值,而统计数据中总是发生的情况是最大会话数上升到不超过 7 左右。我的 JDBC 池大小也很高。

一起使用 JDBC 池和 HAProxy 池通常可以吗?人们以前遇到过这种问题吗?

我对如何解决这个问题有一个想法,即在每次查询之前发送一个“验证查询”。但是那里有一定的开销,我仍然想知道为什么我的 web 应用程序在直接进入 MySQL 时会成功,但在通过 HAProxy 时会断开连接。

我怎样才能进一步调试并获得比“cD”更多的信息?我尝试在调试模式下运行 HAProxy,但它似乎没有透露更多信息。

4

1 回答 1

1

尝试这个:

tune.bufsize 20480
tune.maxrewrite 2048

请参阅ha-docs了解它们的含义。当您进入潜在致命参数的灰色区域时,您必须全神贯注地执行此操作。但值得一试,看看这是否有效。我刚刚解决了一个与文档相比毫无意义的问题。

默认值为 16k 与 1k。

于 2012-11-14T10:14:37.307 回答