求助!用Java对MySQL压力测试中并发连接>500,数据量>30000时报Communications link failure

mcc198775 2012-04-09 04:36:16
MySQL版本:5.5.22 for Linux (x86_64)
设置了max connections=1000

写了一个Java程序,会同时启动500个线程操作数据库,每个线程保持一个Connection
500个线程要总共向数据库insert 30000条数据时,抛了下面的异常。

500线程*10000数据和200线程*100000数据的测试都通过了。

用最简单的
conn = DriverManager.getConnection(path, username,password);
获取的连接。

试过用2台电脑,每台跑300个并发,也会出现同样的错误

感觉是MySQL哪的配置有问题,但就是百思不得其解!
百度相似的错误有人说是连接time out的问题,但是我程序启动就连接数据库并执行测试了,然后就出现异常,并不是在等待较长时间之后执行的测试。

求高人指点迷津!!先谢过了!

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 19,176 milliseconds ago. The last packet sent successfully to the server was 19,176 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3591)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3480)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4021)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2671)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2621)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:842)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:681)
at com.aikaka.performance.mysql.MySqlInsertThread.run(MySqlInsertThread.java:54)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3038)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3491)
... 10 more
...全文
543 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
mcc198775 2012-04-15
  • 打赏
  • 举报
回复
网络环境不稳定时也会抛出这类错误
mcc198775 2012-04-13
  • 打赏
  • 举报
回复
自己解决了,修改参数innodb open files,大于并发连接数

增加的其他配置如下
max_connections=1020
thread_cache_size=128
query_cache_size=1073741824
back_log=500
connect_timeout=600
innodb_open_files=1000


结贴

jastdoit 2012-04-12
  • 打赏
  • 举报
回复
把thread_cache_size值设置范围大点看看
mcc198775 2012-04-09
  • 打赏
  • 举报
回复
java的是毫秒值,19176ms大约是19秒,可能不是timeout的问题

改了interactive timeout和wait timeout=288000,还是同样的错误

改了back log,也没有效果

[Quote=引用 2 楼 的回复:]
这与 back_log 无关,是操作系统在监听队列中所能保持的连接数,有点类似一个缓冲,如果草果限制了就会
connection refused,从配置上来看 不是max_connections的问题,19,176 milliseconds ago大概是5小时,但是这时最后一次!你重启然后再连接试一下。
http://mysqlblog.fivefarmers.com/2010/09/06/d……
[/Quote]
回南山种豆 2012-04-09
  • 打赏
  • 举报
回复
connect_timeout
The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake.
interactive_timeout
The number of seconds the server waits for activity on an interactive connection before closing it.
wait_timeout
The number of seconds the server waits for activity on a noninteractive connection before closing it.
net_read_timeout
The number of seconds to wait for more data from a connection before aborting the read.
net_write_timeout
The number of seconds to wait for a block to be written to a connection before aborting the write.

从以上解释可以看出,connect_timeout在获取连接阶段(authenticate)起作用,interactive_timeout和wait_timeout在连接空闲阶段(sleep)起作用,而net_read_timeout和net_write_timeout则是在连接繁忙阶段(query)起作用。

获取MySQL连接是多次握手的结果,除了用户名和密码的匹配校验外,还有IP->HOST->DNS->IP验证,任何一步都可能因为网络问题导致线程阻塞。为了防止线程浪费在不必要的校验等待上,超过connect_timeout的连接请求将会被拒绝。

即使没有网络问题,也不能允许客户端一直占用连接。对于保持sleep状态超过了wait_timeout(或interactive_timeout,取决于CLIENT_INTERACTIVE标志)的客户端,MySQL会主动断开连接。

即使连接没有处于sleep状态,即客户端忙于计算或者存储数据,MySQL也选择了有条件的等待。在数据包的分发过程中,客户端可能来不及响应(发送、接收、或者处理数据包太慢)。为了保证连接不被浪费在无尽的等待中,MySQL也会选择有条件(net_read_timeout和net_write_timeout)地主动断开连接。

这么多Timeout足以证明MySQL是多么乐于断开连接。而乐于断开连接的背后,主要是为了防止服务端共享资源被某客户端(mysql、mysqldump、页面程序等)一直占用。


这个也可能对你解决问题有益!
回南山种豆 2012-04-09
  • 打赏
  • 举报
回复
这与 back_log 无关,是操作系统在监听队列中所能保持的连接数,有点类似一个缓冲,如果草果限制了就会
connection refused,从配置上来看 不是max_connections的问题,19,176 milliseconds ago大概是5小时,但是这时最后一次!你重启然后再连接试一下。
http://mysqlblog.fivefarmers.com/2010/09/06/debugging-communication-link-failure-exceptions-in-connectorj/
文章应该可以帮你。
rucypli 2012-04-09
  • 打赏
  • 举报
回复
进mysql show processlist 看看是不是连接过多


还有看看back_log这个参数对你是否有帮助

56,687

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧