目前公司采用的是微服务架构,有个商品服务由于需要定时从供应商那边缓存数据,频率2小时一次,每次两条线程,每个线程批量写入2000条,采用的是jdbc的方式进行数据存储,直接使用数据库连接池进行操作
@Autowired private DataSource druidDataSource;
目前连接池配置是 druid.initialSize=1 druid.maxActive=8 druid.minIdle=4 druid.maxWait=60000 druid.testWhileIdle=true druid.validationQuery=select 1 from dual druid.timeBetweenEvictionRunsMillis=60000 druid.minEvictableIdleTimeMillis=1800000 druid.keepAlive=true
每60s的销毁线程执行,最小空闲时间是半个小时,有保活的操作
数据库的wait_timeout和interactive_timeout都是8个小时,用的是阿里云的mysql数据库,配置是单核2G内存
问题:不规律的出现数据库连接不上的问题,每次都会有几个微服务挂掉,报的异常信息都一致,异常信息如下: DruidPooledStatement CommunicationsException, druid version 1.1.21, jdbcUrl : jdbc:mysql:localhost:3306/service_user?useUnicode=true&useSSL=true, testWhileIdle true, idle millis 1, minIdle 4, poolingCount 3, timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 1, driver com.mysql.jdbc.Driver, exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter 2019-12-26 14:25:25.154 ERROR 6 [icator-0] DruidDataSource discard connection
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 7,538 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
我不知道是我的配置有问题,还是数据库的配置不支持4000的同时写入,所以想请教下,希望能在这里解决掉这个问题,谢谢
原提问者GitHub用户shanyuhzz
数据库连接失效的原因主要有以下几点:
数据库本身的问题
数据库服务器宕机或重启。
数据库发生故障,中断网络连接。
这种情况下,数据库上的所有连接都会失效。
连接池参数设置问题
连接超时时间(connectionTimeout)设置过短。
连接空闲时间(maxIdleTime)设置过短。
连接超时或空闲超时后,连接会被回收,从连接池失效。
连接没有及时释放
应用程序使用完连接后未正确关闭连接,导致连接持续占用而最终失效。
数据库并发连接数限制
数据库允许的最大并发连接数不足,造成某些连接无法正常使用。
其他原因
某些SQL语句执行时间过长,导致连接超时。
Bug导致的连接异常关闭。
总的来说,数据库连接失效的主要原因有:
数据库本身问题
连接池参数设置不当
应用程序未正确释放连接
数据库连接数限制
其他原因
要解决这个问题,需要:
检查数据库状态
调整连接池参数
优化SQL查询
增加数据库连接数限制
升级固件/数据库版本来修复Bug
网络连接:确保数据库服务器和微服务之间的网络连接是稳定的,并且没有任何网络问题或防火墙设置导致连接中断。
数据库连接超时设置:您可以检查数据库连接超时的设置。确保数据库服务器的wait_timeout和interactive_timeout设置适当,并且与您的应用程序连接池的配置相匹配。在您的情况下,这些超时设置应该比您的定时任务执行间隔更长,以避免连接在空闲时被数据库服务器关闭。
连接池配置:您的连接池配置看起来是合理的,但您可能需要根据实际情况进行调整。您可以尝试增加连接池的maxActive参数的值,以支持更多的并发连接。您还可以尝试调整minIdle和maxIdle参数的值,以确保连接池中有足够的可用连接。
MySQL的 druid.validationQuery=select 1
原回答者GitHub用户lemontree8801
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。