《故障复盘 · 数据库连接异常关闭》

news2024/9/22 5:36:50

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • 问题背景
    • 问题分析
    • 问题排查
    • 问题结果
    • 知识拓展
    • 总结陈词

CSDN.gif

写在前面的话

博主所在公司的产品线,部署上线了多家客户,遇到的线上故障的场景也较多,这边继续更新一下故障复盘系列,记录并分享一下这些故障的的定位、分析、解决过程。
这里分享的这篇,是由于Druid连接异常关闭,进而引发大范围故障的问题。


问题背景

某天下午,被领导拉到一个群,要求协助开发排查一个由于前一天死循环的问题,导致积累了几天的未申请医嘱记录,数据量较大。最终导致定时器执行“医嘱自动申请”接口的时候,由于执行时间过长,进而报错,错误如下:
image.png

Tips:开局一张图,剩下全靠查。


问题分析

1、该报错的文字版:
Could not commit JDBC transaction; nested exception is java.sql.SQLException: Connection closed.

2、该错误的翻译版:
无法提交JDBC事务,异常原因是连接已关闭

3、继续解释一下:
应该是由于某个事务逻辑执行时间较长,导致提交事务的时候,连接已经被关闭了,无法提交。

4、和开发讨论后得出该医嘱自动申请的逻辑大致如下:
医嘱自动申请接口,在整体逻辑上有特殊性,先是取到一个医嘱列表List,然后遍历处理每条医嘱记录,这里的某条医嘱记录称呼为A,A记录处理的时候又会查出子列表,这里的某个子列表里面的数据称之为B,然后会新开事务去处理子逻辑B,因此导致A的耗时可能较长,又因为B都是新开事务,可能导致A的连接一直空闲,啥事没做。


问题排查

由于手头事情较多,暂无时间拉取实际代码测试。
那先直接从错误查起,既然说连接被关闭,那就查一下数据源等配置。
从项目现场Nacos拷贝了数据库连接池配置,
和连接数量相关的属性,可以看出最大连接是150,获取连接等待超时60秒,但该报错明显不是连接池满,以及获取连接超时。
继续看,和连接关闭的属性相关的,无非:
minEvictableIdleTimeMillis(300秒)
remove-abandoned(开启)
removeAbandonedTimeoutMillis(80秒)

database:
  pool:
    default:
      # 最大连接池数量
      max-active: 150
      # 从连接池获取连接等待超时的时间
      max-wait: 60000
      # 最小连接池数量
      min-idle: 1
      # 配置一个连接在池中最大空闲时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      # 连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行,如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中。
      remove-abandoned: true
      # 回收超时时间
      remove-abandoned-timeout-millis: 80000
      # 打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn
      keep-alive: true
      # 打开PSCache
      pool-prepared-statements: true
      # 指定每个连接上PSCache的大小,Oracle等支持游标的数据库,打开此开关,会以数量级提升性能,具体查阅PSCache相关资料
      max-pool-prepared-statement-per-connection-size: 20

【知识补充】
Druid 部分属性说明:
1、minEvictableIdleTimeMillis:最小空闲时间,默认30分钟,如果连接池中非运行中的连接数大于minIdle,并且那部分连接的非运行时间大于minEvictableIdleTimeMillis,则连接池会将那部分连接设置成Idle状态并关闭;也就是说如果一条连接30分钟都没有使用到,并且这种连接的数量超过了minIdle,则这些连接就会被关闭了。
**2、removeAbandonedTimeoutMillis:**检查连接泄露依据(超时时间),默认5分钟,连接回收的超时时间;设置了removeAbandoned为true,Druid会定期检查线程池溢出的情况,如果不是运行状态,且超过设置的时间就会被回收;
**3、removeAbandoned:**代表是否清理removeAbandonedTimeout秒没有使用的活动连接,清理后并没有放回连接池
4、logAbandoned:连接池收回空闲的活动连接时是否打印消息

Tips:minEvictableIdleTimeMillis 与 removeAbandonedTimeout 这两个参数针对的连接对象不一样,前者针对连接池中的连接对象,后者针对未被close的活动连接,因此针对业务处理逻辑太长,比较重要的还是后者。

【领导继续提问,为啥其他医院量有时候也很大,又正常?】
有什么好说的?那上这家医院的配置?如下所示:
这家医院是旧架构,即SSM框架。可以看到removeAbandonedTimeout配置了900秒,同时removeAbandoned是false,即为不检查。

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
    <property name="driverClassName" value="${datasource.driver}"/>
    <!-- 基本属性 url、user、password -->    <property name="url" value="${datasource.url}"/>
    <property name="username" value="${datasource.username}"/>
    <property name="password" value="${datasource.password}"/>
    <!-- 配置初始化大小、最小、最大 -->
    <property name="initialSize" value="${datasource.initialSize}"/>
    <property name="minIdle" value="${datasource.minIdle}"/>
    <property name="maxActive" value="${datasource.maxActive}"/>    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="5000"/>    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="300000"/>    <property name="validationQuery" value="${jdbc.testSql}"/>
    <property name="testWhileIdle" value="true"/>
    <property name="testOnBorrow" value="false"/>
    <property name="testOnReturn" value="false"/>    <!-- 长时间不使用的连接强制关闭 -->
    <property name="removeAbandoned" value="false"/>
    <!-- 配置开始关闭空闲连接的时间,单位是秒 -->
    <property name="removeAbandonedTimeout" value="900"/>
    <!-- 是否将关闭操作进行日志打印 -->
    <property name="logAbandoned" value="false"/>
    <!--保证连接池中的连接是真实有效的连接,并且空闲连接数维持为minIdle-->
    <property name="keepAlive" value="true"/> 
    <property name="filters" value="stat,config"/>
    <property name="connectionProperties" value="config.decrypt=true;config.decrypt.key=${publickey}" />
</bean>

问题结果

鉴于医嘱的逻辑可能涉及较长时间,因此,80秒可能不够,建议改大。
removeAbandoned 属性依然建议打开,否则会增加连接池泄露风险。


知识拓展

【错误模拟】
晚上有点时间,就想来模拟一下,口说无凭。
其实本地很好重现这个错误,准备如下代码和配置:
1、事务代码里面执行一段更新语法,阻塞一段时间;
2、设置间隔2秒检查,回收打开,超时3秒;
image.png
image.png
可以看到报错如下:
image.png

【源码相关】
image.png
image.png


总结陈词

此篇文章介绍了连接异常关闭 的故障复盘,仅供学习参考。
出现问题并不可靠,主要是能从问题中总结出什么东西,这些不断积累的过程才是令人兴奋的。

Tips:青海长云暗雪山,孤城遥望玉门关。黄沙百战穿金甲,不破楼兰终不还。

CSDN_END.gif

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

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

相关文章

不开放80或443端口也能申请IP SSL证书!

在申请SSL/HTTPS证书时&#xff0c;如果不方便使用域名或者没有域名&#xff0c;就要申请一种特殊的SSL证书——IP SSL证书。但是一般的IP地址证书签发过程中&#xff0c;需要短暂开放80或者443端口才能签发成功。那么问题来了&#xff0c;有的实在不能开放80或者443端口&#…

keil中GD32 MCU IAP中APP的存储地址如何设置?

前面和大家聊过什么是IAP&#xff0c;那么IAP中APP的存储地址该如何设置呢&#xff1f; 以keil为例&#xff0c;打开工程的option选项卡&#xff1a; 将IROM1中的地址改为你想要保存的位置&#xff0c;比如0x08008000开始的位置&#xff1a; 这样通过keil烧录&#xff0c;程序…

记录|.NET上位机开发和PLC通信的实现

本文记录源自&#xff1a;B站视频 实验结果&#xff1a;跟视频做下来是没有问题的。能运行。 目录 前言一、项目Step1. 创建项目Step2. 创建动态图片展示Step3. 创建图片型按钮Step4. 创建下拉框Step1~4的效果展示Step5. 编程实体类操作类Main函数 Step1~5的效果展示Main函数 最…

[Python学习篇] Python PyMysql

什么是PyMysql PyMysql是一个纯 Python 实现的 MySQL 客户端库&#xff0c;允许你在 Python 程序中与 MySQL 数据库进行交互。 安装PyMysql PyMysql地址&#xff1a;https://pypi.org/project/PyMySQL/ pip install pymysql 使用PyMysql 连接mysql import pymysql# 数据库连…

数据库redis命令作业九

1、安装redis&#xff0c;启动客户端、验证。 2、string类型数据的命令操作&#xff1a; &#xff08;1&#xff09; 设置键值&#xff1a; &#xff08;2&#xff09; 读取键值&#xff1a; &#xff08;3&#xff09; 数值类型自增1&#xff1a; &#xff08;4&#xff09; 数…

【单片机毕业设计选题24064】-基于阿里云的鱼塘水质检测系统

系统功能: 主控为STM32F103C8T6&#xff0c;通过PH值传感器、浑浊度传感器、温度传感器采集各项水质数据&#xff0c;系统可设定各参数 的阈值&#xff0c;超过设定的阈值将通过蜂鸣器响来提醒用户做出措施&#xff0c;同时通过ESP-12F WIFI模块将设备连接阿里云 物联网平台…

信通院全景图发布 比瓴科技领跑软件供应链安全,多领域覆盖数字安全服务

近日&#xff0c;中国信息通信研究院在2024全球数字经济大会—数字安全生态建设专题论坛正式发布首期《数字安全护航技术能力全景图》&#xff08;以下简称全景图&#xff09;。 比瓴科技入选软件供应链安全赛道“开发流程安全管控、交互式安全测试、静态安全测试、软件成分分…

rtf是什么格式的文件?rtf格式和word的区别是什么?

RTF是什么格式的文件? RTF&#xff08;富文本格式&#xff0c;Rich Text Format&#xff09;和Word文档&#xff08;以.doc和.docx为扩展名的Microsoft Word文档&#xff09;是两种常用的文本文件格式。它们在文件结构、兼容性、功能和使用场景等方面存在一些显著差异。 比如…

泰迪智能科技江西大数据实验室成功案例介绍说明

高校大数据实验室作为作为支撑高校人培方案实施的核心设施&#xff0c;实验室的建设一定要与学科建设、人才培养充分融合&#xff0c;是一个包含物理空间硬件资源软件资源课程内容的系统化工程。高校在实验室规划过程中&#xff0c;第一要务就是从学科定位出发、结合学校的特色…

ASP.NET MVC-制作可排序的表格组件-PagedList版

环境&#xff1a; win10 参考&#xff1a; 学习ASP.NET MVC(十一)——分页 - DotNet菜园 - 博客园 https://www.cnblogs.com/chillsrc/p/6554697.html ASP.NET MVCEF框架实现分页_ef 异步分页-CSDN博客 https://blog.csdn.net/qq_40052237/article/details/106599528 本文略去…

分布式IO系统BL201 Profinet耦合器

BL201耦合器是一个数据采集和控制系统&#xff0c;基于强大的32 位微处理器设计&#xff0c;采用Linux操作系统&#xff0c;是一种模块化的分布式I/O系统。该系统由3部分组成&#xff1a;现场总线耦合器和各种类型的&#xff08;数字和模拟信号以及特殊功能&#xff09;I/O模块…

部署k8s 1.28.9版本

继上篇通过vagrant与virtualBox实现虚拟机的安装。笔者已经将原有的vmware版本的虚拟机卸载掉了。这个场景下&#xff0c;需要重新安装k8s 相关组件。由于之前写的一篇文章本身也没有截图。只有命令。所以趁着现在。写一篇&#xff0c;完整版带截图的步骤。现在行业这么卷。离…

C#与倍福Plc通信——使用仿真软件模拟倍福PLC运行

前言 我们在编写上位机与倍福PLC通信的过程中,有时候我们没有真实的Plc,但是我们又想提前测试与倍福PLC的通信,那么这个时候我们就可以使用倍福的仿真软件模拟PLC,然后我们上位机就可以与仿真PLC进行通信了,下面进行详细介绍: 1、下载并安装倍福PLC编程软件TwinCAT 安…

Uniapp自定义动态加载组件(2024.7更新)

1.本次介绍如何使用uniapp实现自定义动态加载Loading的组件&#xff0c;可以gif格式&#xff0c;也可以mp4格式等; 编写自定义Loading组件(CustomLoader.vue)&#xff1b;组件中含有“动态接收图片路径”&#xff0c;“10秒超时未false则自动断开关闭Loading”&#xff1b;在全…

基于STC8H4K64TL单片机的触摸功能调试

基于STC8H4K64TL单片机的触摸功能调试 STC8H4K64TL单片机介绍STC8H4K64TL单片机管脚图(48个引脚)STC8H4K64TL单片机串口仿真与串口通信STC8H4K64TL单片机管脚图(32个引脚)STC8H4K64TL单片机管脚图(20个引脚)STC8H系列单片机管脚说明STC8H系列单片机I/O口STC8H系列单片机I…

在MoneyPrinterPlus中使用本地chatTTS语音模型

之前MoneyPrinterPlus在批量混剪,一键AI生成视频这些功能上的语音合成功能都用的是云厂商的语音服务&#xff0c;比阿里云&#xff0c;腾讯云和微软云。 云厂商虽然提供了优质的语音服务&#xff0c;但是用起来还是要收费。 为了各位小伙伴的钱包&#xff0c;现在特意给Money…

基于二次规划优化的OFDM系统PAPR抑制算法的matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于二次规划优化的OFDM系统PAPR抑制算法的matlab仿真. 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 &#xff08;完整程序运行后无水印&#xff09;…

【Springboot】新增profile环境配置应用启动失败

RT 最近接手了一个新的项目&#xff0c;为了不污染别人的环境&#xff0c;我新增了一个自己的环境配置。结果&#xff0c;在启动的时候总是失败&#xff0c;就算是反复mvn clean install也是无效。 问题现象 卡住无法进行下一步 解决思路 由于之前都是能启动的&#xff0c…

zookeeper+kafka的消息队列

zookeeperKafka 两个都是消息队列的工具 消息队列 出现原因&#xff1a;生产者产生的消息与消费者处理消息的效率相差很大。为了避免出现数据丢失而设立的中间件。 在消息的生产者与消费之间设置一个系统&#xff0c;负责缓存生产者与消费者之间的消息的缓存。将消息排序。 优…

nginx生成自签名SSL证书配置HTTPS

一、安装nginx nginx必须有"--with-http_ssl_module"模块 查看nginx安装的模块&#xff1a; rootecs-7398:/usr/local/nginx# cd /usr/local/nginx/ rootecs-7398:/usr/local/nginx# ./sbin/nginx -V nginx version: nginx/1.20.2 built by gcc 9.4.0 (Ubuntu 9.4.0…