疑似连接池不够大导致的“Expected to read 4 bytes, read 0 bytes before connection ……“异常_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 疑似连接池不够大导致的“Expected to read 4 bytes, read 0 bytes before connection ……“异常

疑似连接池不够大导致的“Expected to read 4 bytes, read 0 bytes before connection ……“异常

 2011/11/8 7:52:45  weiqiang.yang  http://vivisidea.iteye.com  我要评论(0)
  • 摘要:上周应用突然出现奇怪的异常,奇怪的地方有几点1.应用没有做任何代码更新2.从数据库看到的应用连接是正常的,连接数量也不多3.之前很长一段时间应用没有出现过这个异常4.异常出现后一段时间内应用似乎无法从数据库取得数据,数据库访问出现卡死状态,但是过几分钟后又自动恢复正常5.重启不能解决问题6.同一台服务器上连同一个数据库的的另一个应用(连接池配置一样),没有出现这个问题java.io.EOFException:Cannotreadresponsefromserver
  • 标签:for 连接 连接池
上周应用突然出现奇怪的异常,奇怪的地方有几点
1. 应用没有做任何代码更新
2. 从数据库看到的应用连接是正常的,连接数量也不多
3. 之前很长一段时间应用没有出现过这个异常
4. 异常出现后一段时间内应用似乎无法从数据库取得数据,数据库访问出现卡死状态,但是过几分钟后又自动恢复正常
5. 重启不能解决问题
6. 同一台服务器上连同一个数据库的的另一个应用(连接池配置一样),没有出现这个问题

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:2539)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2989)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2978)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3526)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
        at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1362)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:185)
        at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQuery(MappedStatement.java:221)
        at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:189)
        at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForObject(MappedStatement.java:120)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:518)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:493)
        at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:106)
        at org.springframework.orm.ibatis.SqlMapClientTemplate$1.doInSqlMapClient(SqlMapClientTemplate.java:270)
        at ……



google了一些文章看了,这篇http://hi.baidu.com/liyanjiespace/blog/item/750b1051293c5812367abe26.html文章说到服务器时间会导致这个问题,并且解决方案是修改连接池配置,让连接池每次获取连接之前检查该连接是否可用,可是我们服务器并没有修改过时间,而且我们的dbcp连接池已经配置过testOnBorrow和validationQuery,所以应该不是这个问题
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${db.driver}" />
		<property name="url" value="${db.url}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />
		<property name="initialSize" value="5" />        <!-- 初始连接数量 -->
		<property name="maxActive" value="15" />         <!-- 最大连接数量 -->
		<property name="maxIdle" value="5" />            <!-- 空闲连接数量 -->
		<property name="maxWait" value="600000" />       <!-- 一个查询10分钟内没有返回,自动放弃 -->
		
		<property name="validationQuery" value="SELECT 1" />   <!-- 数据库连接可用性测试语句 -->
		<property name="testOnBorrow" value="true" />          <!-- 每次获取一个连接的时候,验证一下连接是否可用,语句在validationQuery里面 -->
		<property name="removeAbandoned" value="true" />       <!-- 自动处理连接未关闭的问题,Setting this to true can recover db connections from poorly written applications which fail to close a connection.  -->
		<property name="removeAbandonedTimeout" value="300" /> <!-- 连接使用后5分钟未关闭,则抛弃 -->
		
		<!-- 每5分钟检查一次,每次检查3个连接,如果连接空闲时间达到5分钟,则认为可以Evict,从连接池排除 
		     空闲的连接是否排除对连接池似乎没有太大影响,我们只需要保证每次获取的连接都可用,所以暂时先不开启
		<property name="timeBetweenEvictionRunsMillis" value="300000" />
		<property name="numTestsPerEvictionRun" value="3" />
		<property name="minEvictableIdleTimeMillis" value="320000" />-->
	</bean>


然后想到既然另一个应用相同的配置没问题,那这两个应用的区别是什么?
引用另一个应用是后台应用,没有用户直接使用,而出问题的这个应用是web应用,有用户使用。
会不会是系统使用者比预想的要多?原本预期是同时大概会有10个人左右,一问,现在居然有30+人。。。汗,于是将maxActive加到50,initialSize加到15,重启,问题消失,今天查了周末的log,也没有出现过这个异常,当然也有可能是连接池设置大了之后导致问题出现需要的时间更长,所以并不能肯定就是连接池不够大的问题导致的,还需要继续的观察~

记录下,以后有新情况再更新。
发表评论
用户名: 匿名