Apache Druid连接回收引发的血案

问题

线上执行大批量定时任务,发现SQL执行失败的报错:

CommunicationsException, druid version 1.1.10, 
jdbcUrl : jdbc:mysql://xxx?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull,testWhileIdle true, idle millis 658108, minIdle 2, poolingCount 1,timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 658108, driver com.mysql.jdbc.Driver, exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failureThe last packet successfully received from the server was 658,107 milliseconds ago.  The last packet sent successfully to the server was 0 milliseconds ago.at sun.reflect.GeneratedConstructorAccessor60.newInstance(Unknown Source)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:981)at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3465)at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3365)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3805)at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3188)at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:465)at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3185)at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeQuery(PreparedStatementProxyImpl.java:181)at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:228)at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57)at org.hibernate.loader.Loader.getResultSet(Loader.java:2304)

追查

从错误日志看来,是连接MySQL超时,但是这个超时时间感觉有点离谱,查看了一下执行的SQL,是非常简单的SQL,理论上不可能造成超时。
联系DBA,看看MySQL的日志能否发现什么蛛丝马迹。

原因

经过DBA排查,确认是MySQL的空闲连接清理参数配置,MySQL的interactive_timeout参数指定了连接空闲多久后会被回收掉,缺省配置为600秒。
在这里插入图片描述

问题初步定位,是因为数据库连接池Druid持有的数据库连接,已经被MySQL回收,此时有SQL执行时,已经被回收掉的连接再此被分配,就会导致这个报错。
那么问题来了,为什么数据库连接池没有感知到这个连接已经被回收了呢?

连接池是怎么判断一条连接是Idle状态的?

带着疑问,翻找Druid文档,发现两个配置:

  • minEvictableIdleTimeMillis:最小空闲时间,默认30分钟,如果连接池中非运行中的连接数大于minIdle,并且那部分连接的非运行时间大于minEvictableIdleTimeMillis,则连接池会将那部分连接设置成Idle状态并关闭;也就是说如果一条连接30分钟都没有使用到,并且这种连接的数量超过了minIdle,则这些连接就会被关闭了。

  • maxEvictableIdleTimeMillis:最大空闲时间,默认7小时,如果minIdle设置得比较大,连接池中的空闲连接数一直没有超过minIdle,这时那些空闲连接是不是一直不用关闭?当然不是,如果连接太久没用,数据库也会把它关闭,这时如果连接池不把这条连接关闭,系统就会拿到一条已经被数据库关闭的连接。为了避免这种情况,Druid会判断池中的连接如果非运行时间大于maxEvictableIdleTimeMillis,也会强行把它关闭,而不用判断空闲连接数是否小于minIdle。

原来Druid是根据这两个配置来确认什么时候回收空闲的连接,为了验证是否如此,看一下源码中如何使用这两个配置。

我们使用的Druid版本是1.1.10。

com.alibaba.druid.pool.DruidDataSource

    public class DestroyTask implements Runnable {@Overridepublic void run() {shrink(true, keepAlive);if (isRemoveAbandoned()) {removeAbandoned();}}}

追踪源码,定位到DruidDataSource,*DestroyTask shrink()*负责释放连接:

public void shrink(boolean checkTime, boolean keepAlive) {try {lock.lockInterruptibly();} catch (InterruptedException e) {return;}int evictCount = 0;int keepAliveCount = 0;try {if (!inited) {return;}final int checkCount = poolingCount - minIdle;final long currentTimeMillis = System.currentTimeMillis();for (int i = 0; i < poolingCount; ++i) {DruidConnectionHolder connection = connections[i];if (checkTime) {if (phyTimeoutMillis > 0) {long phyConnectTimeMillis = currentTimeMillis - connection.connectTimeMillis;if (phyConnectTimeMillis > phyTimeoutMillis) {evictConnections[evictCount++] = connection;continue;}}long idleMillis = currentTimeMillis - connection.lastActiveTimeMillis;if (idleMillis < minEvictableIdleTimeMillis) {break;}if (checkTime && i < checkCount) {evictConnections[evictCount++] = connection;} else if (idleMillis > maxEvictableIdleTimeMillis) {evictConnections[evictCount++] = connection;} else if (keepAlive) {keepAliveConnections[keepAliveCount++] = connection;}} else {if (i < checkCount) {evictConnections[evictCount++] = connection;} else {break;}}}.........}

在*shrink()*方法中我们找到了minEvictableIdleTimeMillis和maxEvictableIdleTimeMillis,等等,好像哪里不对?

		if (idleMillis < minEvictableIdleTimeMillis) {break;}if (checkTime && i < checkCount) {evictConnections[evictCount++] = connection;} else if (idleMillis > maxEvictableIdleTimeMillis) {evictConnections[evictCount++] = connection;} else if (keepAlive) {keepAliveConnections[keepAliveCount++] = connection;}

这里与文档的解释好像不一样?当连接空闲时间小于minEvictableIdleTimeMillis,退出循环检测,如果大于minEvictableIdleTimeMillis,判断空闲时间大于maxEvictableIdleTimeMillis,将连接加入需要释放的数组中。

那也就是说,如果按照缺省配置,minEvictableIdleTimeMillis 30分钟,maxEvictableIdleTimeMillis 7天,确实可能会出现Druid认为连接还存活着,但MySQL判断空闲时间超过配置,将会回收连接。

配置建议

maxEvictableIdleTimeMillis 要小于等于 MySQL Server端interactive_timeout 配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/190718.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java事务详解

一、事务的理解&#xff1a; 1、事务的特性&#xff1a; 1) 原子性&#xff08;atomicity&#xff09;&#xff1a;事务是数据库的逻辑工作单位&#xff0c;而且是必须是原子工作单位&#xff0c;对于其数据修改&#xff0c;要么全部执行&#xff0c;要么全部不执行。 2) 一致性…

Vatee万腾外汇数字化策略:Vatee科技决策力的未来引领

在外汇市场&#xff0c;Vatee万腾通过其前瞻性的外汇数字化策略&#xff0c;正引领着科技决策的未来。这一数字化策略的崭新愿景为投资者提供了更智慧、更高效的外汇投资体验&#xff0c;成为科技决策领域的翘楚。 Vatee万腾的外汇数字化策略是科技决策力未来引领的典范。通过运…

消息队列之初识Rabbit及安装

文章目录 一、MQ的相关概念1.什么是MQ&#xff1f;2.为什么要用MQ2.1流量消峰2.2应用解耦2.3异步处理 3.MQ 的分类3.1.ActiveMQ3.2.Kafka3.3.RocketMQ3.4.RabbitMQ 4.MQ 的选择4.1.Kafka4.2.RocketMQ4.3.RabbitMQ 二、RabbitMQ的相关概念1.四大核心概念2.RabbitMQ 核心部分3.Ra…

游戏AI:游戏开发和运营的新增长点

游戏AI&#xff08;Game AI&#xff09;是指在游戏开发运营的过程中模拟人类玩家或创建虚构性对手行为的人工智能技术。游戏AI的目标是增强游戏的互动性、可玩性和挑战性&#xff0c;使游戏中的角色能够智能地做出决策和行为。在游戏的开发和运营过程中使用人工智能技术&#x…

caffe搭建squeezenet网络的整套工程

之前用pytorch构建了squeezenet&#xff0c;个人觉得pytorch是最好用的&#xff0c;但是有的工程就是需要caffe结构的&#xff0c;所以本篇也用caffe构建一个squeezenet网络。 数据处理 首先要对数据进行处理&#xff0c;跟pytorch不同&#xff0c;pytorch读取数据只需要给数据…

【C++】类和对象(2)--构造函数

目录 一 概念 二 构造函数特性 三 默认构造函数 一 概念 对于以下Date类&#xff1a; class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout << _year << "-" << _month <…

Qt贝塞尔曲线

目录 引言核心代码基本表达绘制曲线使用QEasingCurve 完整代码 引言 贝塞尔曲线客户端开发中常见的过渡效果&#xff0c;如界面的淡入淡出、数值变化、颜色变化等等。为了能够更深的了解地理解贝塞尔曲线&#xff0c;本文通过Demo将贝塞尔曲线绘制出来&#xff0c;如下所示&am…

DevChat:开发者专属的基于IDE插件化编程协助工具

DevChat&#xff1a;开发者专属的基于IDE插件化编程协助工具 一、DevChat 的介绍1.1 DevChat 简介1.2 DevChat 优势 二、DevChat 在 VSCode 上的使用2.1 安装 DevChat2.2 注册 DevChat2.3 使用 DevChat 三、DevChat 的实战四、总结 一、DevChat 的介绍 在AI浪潮的席卷下&#x…

基于开源项目OCR做一个探究(chineseocr_lite)

背景&#xff1a;基于图片识别的技术有很多&#xff0c;应用与各行各业&#xff0c;我们公司围绕电子身份证识别自动录入需求开展&#xff0c;以下是我的研究心得 技术栈&#xff1a;python3.6&#xff0c;chineseocr_lite的onnx推理 环境部署&#xff1a;直接上截图&#xff…

c语言-数据结构-栈和队列的实现和解析

目录 一、栈 1、栈的概念 1.2 栈的结构 2、栈的创建及初始化 3、压栈操作 4、出栈操作 5、显示栈顶元素 6、显示栈空间内元素的总个数 7、释放栈空间 8、测试栈 二、队列 1、队列的概念 1.2 队列的结构 2、队列的创建及初始化 3、入队 4、出队 5、显示队头、队…

在Spring Boot中使用JTA实现对多数据源的事务管理

了解事务的都知道&#xff0c;在我们日常开发中单单靠事务管理就可以解决绝大多数问题了&#xff0c;但是为啥还要提出JTA这个玩意呢&#xff0c;到底JTA是什么呢&#xff1f;他又是具体来解决啥问题的呢&#xff1f; JTA JTA&#xff08;Java Transaction API&#xff09;是…

CG Magic分享效果图中VRay的灯光设置分析

效果图制作中&#xff0c;一张图VRay效果图好不好看主要看灯光、材质、模型、相机、后期这五点。VRay的灯光设置来说是极为重要的。 VRay灯光设置不好&#xff0c;就会出现vray灯光颜色不能正常显示再或是vray的灯光不亮的问题。 vray的灯光怎么设置才能使效果图展现的更加真实…

LabVIEW中如何在网络上使用远程VI服务器

LabVIEW中如何在网络上使用远程VI服务器 如何在网络上使用远程VI服务器&#xff1f; 解答: 首先&#xff0c;需要在远程的计算机上打开一个在VI服务器上的LabVIEW应用程序的引用。这可以通过“Open ApplicationReference“函数实现。然后用“Open VI Reference”函数打开一个…

外贸开发信邮箱如何选?群发邮件有效技巧?

外贸开发信邮箱用哪种好&#xff1f;QQ邮箱群发邮件怎么发&#xff1f; 一个有效的外贸开发信邮箱可以帮助您建立联系、推销产品&#xff0c;并与潜在客户进行沟通。在本文中&#xff0c;蜂邮EDM将分享一些关于如何选择外贸开发信邮箱的建议&#xff0c;以确保您能够与全球客户…

大数据-玩转数据-Flume

一、Flume简介 Flume提供一个分布式的,可靠的,对大数据量的日志进行高效收集、聚集、移动的服务,Flume只能在Unix环境下运行。Flume基于流式架构,容错性强,也很灵活简单。Flume、Kafka用来实时进行数据收集,Spark、Flink用来实时处理数据,impala用来实时查询。二、Flume…

计算机视觉:使用opencv实现银行卡号识别

1 概述 1.1 opencv介绍 OpenCV是Open Source Computer Vision Library&#xff08;开源计算机视觉库&#xff09;的简称&#xff0c;由Intel公司在1999年提出建立&#xff0c;现在由Willow Garage提供运行支持&#xff0c;它是一个高度开源发行的计算机视觉库&#xff0c;可以…

ESP32 C3 smartconfig一键配网报错

AP配网 在调试我的esp32c3的智能配网过程中&#xff0c;发现ap配网使用云智能App是可以正常配置的。 切记用户如果在menu菜单里使能AP配网&#xff0c;默认SSID名字为adh_PK值_MAC后6位。用户可以修改这个apssid的键值&#xff0c;但是要使用云智能app则这个名字的开头必须为ad…

电源基础元件

文章目录 电源基础元件理想电压源理想电流源受控电源 电源基础元件 理想电压源 定义 其两端电压总能保持定值或一定的时间函数&#xff0c;其值与流过它的电流i无关的元件叫理想电压源 理想电压源的电压、电流关系 1.电源两端电压由电源本身决定&#xff0c;与外电路无关&…

windows安装nginx

一、下载安装Nginx 1、官网下载地址&#xff1a;nginx: download 2、下载教程&#xff1a;选择最新的Stable version&#xff08;稳定版本&#xff09;下载到本地 3、下载完成后&#xff0c;解压放入本地非中文的文件夹中&#xff1a; 4、启动nginx&#xff1a;切勿直接双击n…

2390 高校实验室预约系统JSP【程序源码+文档+调试运行】

摘要 本文介绍了一个高校实验室预约系统的设计和实现。该系统包括管理员、教师和学生三种用户&#xff0c;具有基础数据管理、学生管理、教师管理、系统公告管理、实验室管理、实验室预约管理和系统管理等模块。通过数据库设计和界面设计&#xff0c;实现了用户友好的操作体验…