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.mzph.cn/news/140930.shtml

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

相关文章

Zigbee智能家居方案设计

背景 目前智能家居物联网中最流行的三种通信协议&#xff0c;Zigbee、WiFi以及BLE&#xff08;蓝牙&#xff09;。这三种协议各有各的优势和劣势。本方案基于CC2530芯片来设计&#xff0c;CC2530是TI的Zigbee芯片。 网关使用了ESP8266CC2530。 硬件实物 节点板子上带有继电器…

Hosts File Editor 实用工具

我一般手工编辑hosts文件&#xff0c;我想给hosts文件加一个开关&#xff0c;本想自己实现&#xff0c;但是忽然发现微软已经提供了官方的解决方案&#xff0c;感觉有能人。 对文件的行的修改被抽象成了一个开关。腻害&#xff01;&#xff01;&#xff01;

◢Django 自写分页与使用

目录 1、设置分页样式,并展示到浏览器 2、模拟页码 3、生成分页 4、数据显示 5、上一页下一页 6、数据库的数据分页 7、封装分页 8、使用封装好的分页 建立好app后&#xff0c;设置路径path(in2/,views.in2)&#xff0c;视图def in2(request): &#xff0c;HTML: in2.html…

RK3568笔记五:基于Yolov5的训练及部署

若该文为原创文章&#xff0c;转载请注明原文出处。 一. 部署概述 环境&#xff1a;Ubuntu20.04、python3.8 芯片&#xff1a;RK3568 芯片系统&#xff1a;buildroot 开发板&#xff1a;ATK-DLRK3568 开发主要参考文档&#xff1a;《Rockchip_Quick_Start_RKNN_Toolkit2_C…

开源知识库软件xwiki在Windows下的安装

文章目录 开源知识库软件-xwiki在windows上的部署0、参考文档1、前置环境准备1.1、Windows版本及系统配置1.2、JDK11安装1.3、Tomcat9安装1.4、MySQL5.7数据库的安装 2、xwiki安装3、配置3.1、修改配置支持对文档内容进行搜索 4、问题解决4.1、附件无法上传问题4.1、附件无法下…

FreeRTOS知识梳理

一、RTOS:Real time operating system,中文意思为 实时操作系统&#xff0c;它是一类操作系统&#xff0c;比如uc/OS、FreeRTOS、RTX、RT-Thread 这些都是实时操作系统。 二、移植FreeRTOS到STM32F103C8T6上 interface选择CMSIS_V1,RCC选择Crystal Ceramic Resonator 。 …

海康威视(iVMS)综合安防系统任意文件上传漏洞复现 [附POC]

文章目录 海康威视&#xff08;iVMS&#xff09;综合安防系统任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 海康威视&#xff08;iVMS&#xff09;综合安防系统任意文件上传漏洞复…

[PyTorch][chapter 62][强化学习-基本概念]

前言&#xff1a; 目录&#xff1a; 强化学习概念 马尔科夫决策 Bellman 方程 格子世界例子 一 强化学习 强化学习 必须在尝试之后&#xff0c;才能发现哪些行为会导致奖励的最大化。 当前的行为可能不仅仅会影响即时奖赏&#xff0c;还有影响下一步奖赏和所有奖赏 强…

使用Inis搭配内网穿透实现Ubuntu上快速搭建博客网站远程访问

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

在 uniapp 中 一键转换单位 (px 转 rpx)

在 uniapp 中 一键转换单位 px 转 rpx Uni-app 官方转换位置利用【px2rpx】插件Ctrl S一键全部转换下载插件修改插件 Uni-app 官方转换位置 首先在App.vue中输入这个&#xff1a; uni.getSystemInfo({success(res) {console.log("屏幕宽度", res.screenWidth) //屏…

酷柚易汛ERP - 商品库存余额表操作指南

1、应用场景 商品库存余额表用于查询商品在各仓库的实际结存量、单位成本以及成本等明细。 2、主要操作 打开【仓库】-【商品库存余额表】&#xff0c;可筛选仓库、商品、商品类别&#xff0c;导出/打印等操作见【销货单】不再赘述。 3、分享操作 库存余额分享&#xff0c;…

CCLink转Modbus TCP网关_MODBUS网口设置

兴达易控CCLink转Modbus TCP网关是一种用于连接CCLink网络和Modbus TCP网络的设备。它提供了简单易用的MODBUS网口设置&#xff0c;可以帮助用户轻松地配置和管理网络连接 1 、网关做为MODBUS主站 &#xff08;1&#xff09;将电脑用网线连接至网关的P3网口上。 &#xff08;…

计算机网络(一)

一、什么是计算机网络、计算机协议&#xff1f; 计算机网络就是由计算机作为收发端&#xff0c;不同计算机相互连接的网络&#xff0c;包括互联网&#xff08;Internet&#xff09;&#xff0c;公司或者家用网络&#xff08;intranet&#xff09;等等&#xff1b;其中Internet…

【C语言 | 指针】C指针详解(经典,非常详细)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【数据结构】非递归实现二叉树的前 + 中 + 后 + 层序遍历(听说面试会考?)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&…

利用角色roles上线wordpress项目

角色订制&#xff1a;roles ① 简介 对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。   roles 用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文…

CentOS7、CentOS8 如何修改ip信息(修改网络信息)(无图形界面)(亲测可用)

文章目录 CentOS 7方法一&#xff1a;使用 nmcli 命令方法二&#xff1a;编辑配置文件&#xff08;我的CentOS7是使用这种方法&#xff0c;亲测可用&#xff09; CentOS 8方法一&#xff1a;使用 nmcli 命令方法二&#xff1a;编辑配置文件 在 CentOS 系统中&#xff0c;如果你…

详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await

同步&异步的概念 在讲这四种异步方案之前&#xff0c;我们先来明确一下同步和异步的概念&#xff1a; 所谓同步(synchronization)&#xff0c;简单来说&#xff0c;就是顺序执行&#xff0c;指的是同一时间只能做一件事情&#xff0c;只有目前正在执行的事情做完之后&am…

Halcon WPF 开发学习笔记(2):Halcon导出c#脚本和WPF初步开发

文章目录 前言HalconC#教学简单说明如何二开机器视觉如何二次开发Halcon导出Halcon脚本新建WPF项目&#xff0c;导入Halcon脚本和Halcon命名空间 前言 我目前搜了一下我了解的机器视觉软件&#xff0c;有如下特点 优点缺点兼容性教学视频(B站前三播放量)OpenCV开源&#xff0…

Vue 组件化编程 和 生命周期

目录 一、组件化编程 1.基本介绍 : 2.原理示意图 : 3.全局组件示例 : 4.局部组件示例 : 5.全局组件和局部组件的区别 : 二、生命周期 1.基本介绍 : 2.生命周期示意图 : 3.实例测试 : 一、组件化编程 1.基本介绍 : (1) 开发大型应用的时候&#xff0c;页面往往划分成…