采用SpringBoot1.2+Mybatis+tomcat,双数据源,其中一个数据源没有配置数据库连接池信息。
结构如下:
spring:
datasource:
test1:
username:
password:
validationQuery:
testWhileIdle:
test2:
username:
password:
报错信息
程序晚上11点到第二天下午三点未进行任何操作,然后报数据库连接重置Connection Reset。
解决办法及原因分析汇总
大概率可能(数据库连接池配置问题)
通过搜寻资料,归纳深层原因如下:
- Linux下会自动断超过时间的连接。(这个异常通常在Linux服务器上会发生,原因是Linux系统会主动断开一个长时间没有通信的连接)
- 数据库会自动断超过时间的连接。(与数据库设置有关)
研究了一下数据库连接池的知识。
SpringBoot1.5之前默认Tomcat数据库连接池,底层属于DBCP,所以研究DBCP的配置项。
DBCP连接池的配置
<Resource name="jdbc/TestDB" JNDI数据源的name
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver" JDBC驱动类
url=""
username="" 访问数据库用户名
password="" 访问数据库的密码
maxActive="80" 最大活动连接
initialSize="10" 初始化连接
maxIdle="60" 最大空闲连接
minIdle="10" 最小空闲连接
maxWait="3000" 从池中取连接的最大等待时间,单位ms.
validationQuery = "SELECT 1" 验证使用的SQL语句
testWhileIdle = "true" 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testOnBorrow = "false" 借出连接时不要测试,否则很影响性能
timeBetweenEvictionRunsMillis = "30000" 每30秒运行一次空闲连接回收器
minEvictableIdleTimeMillis = "1800000" 池中的连接空闲30分钟后被回收
numTestsPerEvictionRun="3" 在每次空闲连接回收器线程(如果有)运行时检查的连接数量
removeAbandoned="true" 连接泄漏回收参数,当可用连接数少于3个时才执行
removeAbandonedTimeout="180" 连接泄漏回收参数,180秒,泄露的连接可以被删除的超时值
/>
配置信息说明可以借鉴阿里巴巴连接池:https://github/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
解决办法:
针对连接池失效的几个重要参数做下说明。
1、testOnReturn,testOnBorrow这两个参数为true,表示会在每次请求之前和之后进行连接池测试,如果连接失效,就会将这条连接对象销毁,创建一个新的连接对象,但是本次数据库操作也就失败了。对于读操作可能没什么问题,再请求一次就行了,但对于充值、定时任务等重要写操作来说还不够完美。(PS:使用这两个参数,一定要配置validationQuery参数,这样才会生效。)
2、为了解决以上问题,保证每次操作都有正常的连接池使用,我们来了解一下testWhileIdle参数。这个参数为true时候,表示空闲时是进行验证,检查对象是否有效。然后minEvictableIdleTimeMillis配合timeBetweenEvictionRunsMillis,每过timeBetweenEvictionRunsMillis秒对连接池进行一次检测,将对象闲置时间超过minEvictableIdleTimeMillis秒的对象进行销毁,创建新的对象来取代。这样就能保证时刻都有正常的连接池对象存在。
更换连接池
采用阿里巴巴数据库连接池(与DBCP一样)
总结
数据库连接池的配置项要深入理解。
参考文章:
解决MySQL8小时自动断开连接的问题(DBCP配置)
https://www.jianshu/p/048974470bf3
更多推荐
实战踩坑问题解决系列--Oracle数据库连接重置Connection Reset
发布评论