深度解析 MySQL 与 Spring Boot 长耗时进程:从故障现象到根治方案(含 Tomcat 重启必要性分析)

news2025/5/15 13:20:05

一、典型故障现象与用户痛点

在高并发业务场景中,企业级 Spring Boot 应用常遇到以下连锁故障:

  • 用户侧:网页访问超时、提交表单无响应,报错 “服务不可用”。
  • 运维侧:监控平台报警 “数据库连接池耗尽”,Tomcat 日志频繁输出GetConnectionTimeoutException: wait millis 6000, active 100(等待 6 秒未获取连接,当前 100 个连接被占满)。
  • 数据库侧:执行SHOW PROCESSLIST发现 167 个 MySQL 进程,其中 100 + 个进程Time字段显示 “3600”(已运行 1 小时),状态为Sending dataLocked

二、故障根因定位:从现象到本质

2.1 核心错误:GetConnectionTimeoutException

该异常的直接原因是连接池无法在指定时间内提供可用连接。结合 MySQL 长进程现象,根因可归纳为以下四类(附权威验证):

故障类型现象特征权威依据
连接池配置不合理连接池maxPoolSize过小(如设为 50),但业务并发量达 100TPS,导致连接池被占满HikariCP 官方文档:建议maxPoolSize为 CPU 核心数 ×2+1(参考HikariCP 配置指南)
连接泄露代码未关闭Connection/Statement,连接池idleConnections持续下降至 0JDBC 规范:Connection必须显式关闭(JDK7 + 推荐try-with-resources自动回收)
慢查询 / 长事务MySQL 进程Time字段超长(如 3600 秒),Info显示无索引的大表查询MySQL 官方文档:SHOW PROCESSLIST可定位长查询(参考MySQL 8.0 文档)
连接有效性失效MySQLwait_timeout设为 3600 秒(1 小时),但连接池未验证连接存活,导致持有无效连接HikariCP 文档:需配置connection-test-query验证连接(参考HikariCP FAQ)

三、分阶段解决方案:从临时止血到根治

3.1 临时止血:手动终止 MySQL 长进程(用户无法访问时)

当用户已无法访问,需快速释放数据库资源:

步骤 1:筛选危险进程

通过以下 SQL 定位 “执行中且耗时超 600 秒” 的进程(避免终止Sleep状态的空闲连接):

sql

SELECT ID, USER, HOST, DB, TIME, STATE, INFO 
FROM information_schema.processlist 
WHERE TIME > 600 AND STATE != 'Sleep';

步骤 2:安全终止进程

执行KILL [进程ID]终止长进程(注意:可能导致未提交事务回滚,需确认业务容忍度):

sql

KILL 1234; -- 终止ID为1234的长查询进程  

3.2 关键问题:终止 MySQL 进程后,是否需要重启 Tomcat?

结论通常无需重启 Tomcat,但需满足连接池配置正确;若配置不当,可能需要重启。

3.2.1 无需重启的场景(连接池配置正确)

若连接池(如 HikariCP)配置了连接有效性验证超时回收机制,Tomcat 可自动回收无效连接并创建新连接:

  • 连接有效性验证connection-test-query):
    连接池在获取连接时,会执行轻量级 SQL(如SELECT 1)验证连接是否存活。若 MySQL 进程已被终止,连接失效,验证失败后连接池会丢弃该连接并创建新连接。

  • 超时回收机制idle-timeout/max-lifetime):
    空闲连接超过idle-timeout会被主动关闭;连接存活超过max-lifetime会被强制回收,避免持有老化连接。

3.2.2 需要重启的场景(连接池配置不当)

若未配置连接有效性验证,或idle-timeout大于 MySQL 的wait_timeout,可能出现以下问题:

  • 连接池持有已被 MySQL 关闭的无效连接(Connection对象未被销毁,但底层 TCP 连接已断开)。
  • 后续请求从连接池获取到无效连接,执行 SQL 时抛出SQLNonTransientConnectionException: No operations allowed after connection closed

此时需重启 Tomcat,强制销毁所有连接池中的无效连接,并重新初始化连接池。

3.2.3 验证是否需要重启(关键操作)

终止 MySQL 进程后,通过以下步骤判断是否需要重启:

验证项操作方法无需重启的特征需要重启的特征
应用日志查看 Tomcat 日志(如catalina.out出现HikariPool-1 - Closing connection com.mysql.cj.jdbc.ConnectionImpl@xxx(无效连接被回收)出现SQLNonTransientConnectionException: No operations allowed after connection closed(无效连接被重复使用)
连接池监控访问/actuator/metrics(需启用 Spring Actuator)hikaricp.connections.idle(空闲连接数)逐渐上升,hikaricp.connections.active(活跃连接数)下降hikaricp.connections.idle持续为 0,hikaricp.connections.pending(等待连接数)大于 0

3.3 中期治理:连接池与 MySQL 配置优化

3.3.1 HikariCP 连接池配置(解决GetConnectionTimeoutException

通过以下配置平衡连接利用率与稳定性(参考 HikariCP 官方推荐):

properties

# application.properties  
spring.datasource.hikari.maximum-pool-size=20        # CPU核心数×2+1(如4核设为9,高并发可适当调大)  
spring.datasource.hikari.minimum-idle=5             # 最小空闲连接数(建议≤maxPoolSize)  
spring.datasource.hikari.connection-timeout=30000   # 连接获取超时时间(30秒,避免短时间重试)  
spring.datasource.hikari.idle-timeout=1800000       # 空闲连接超时(30分钟,小于MySQL的wait_timeout)  
spring.datasource.hikari.max-lifetime=3600000       # 连接最大存活时间(1小时,避免连接老化)  
spring.datasource.hikari.leak-detection-threshold=30000  # 连接泄露检测(30秒未关闭则日志报警)  
spring.datasource.hikari.connection-test-query=SELECT 1  # 验证连接存活(避免持有MySQL已关闭的连接)  

3.3.2 MySQL 配置(自动终止长查询 + 回收空闲连接)

通过以下参数从数据库层拦截长耗时操作(参考 MySQL 8.0 官方文档):

ini

# my.cnf(MySQL配置文件)  
[mysqld]  
max_execution_time=5000       # 单个查询最大执行时间(5秒,超时自动终止)  
wait_timeout=3600             # 空闲连接超时(1小时,需大于连接池的idle-timeout)  
interactive_timeout=3600      # 交互式连接超时(与wait_timeout一致)  
slow_query_log=1              # 开启慢查询日志(记录执行超2秒的查询)  
slow_query_log_file=/var/log/mysql/slow.log  
long_query_time=2             # 慢查询阈值(2秒)  

3.4 长期根治:代码与事务优化

3.4.1 修复连接泄露(解决 “连接被永久占用”)

错误代码示例(未关闭资源):

java

// 反例:未使用try-with-resources,连接可能未关闭  
Connection conn = dataSource.getConnection();  
Statement stmt = conn.createStatement();  
ResultSet rs = stmt.executeQuery("SELECT * FROM big_table");  
// 业务逻辑...  
// 未显式关闭conn/stmt/rs!  

正确代码示例(自动关闭资源):

java

// 正例:JDK7+使用try-with-resources自动关闭  
try (Connection conn = dataSource.getConnection();  
     Statement stmt = conn.createStatement();  
     ResultSet rs = stmt.executeQuery("SELECT * FROM big_table")) {  
    // 业务逻辑...  
} // 自动关闭conn/stmt/rs(无需finally)  

3.4.2 控制事务超时(解决 “长事务占用连接”)

通过 Spring 的@Transactional注解设置事务超时时间(单位:秒),超时自动回滚并释放连接(参考Spring 事务文档):

java

@Service  
public class OrderService {  
    // 事务超时30秒(包含查询、锁等待等所有操作)  
    @Transactional(timeout = 30)  
    public void updateOrder() {  
        // 执行可能耗时的SQL(如更新大表)  
        orderMapper.updateLargeTable();  
    }  
}  

四、效果验证与监控体系

4.1 验证自动恢复

手动终止 MySQL 长进程后,通过以下方式确认连接池自动重连:

  • 应用日志:检查是否有HikariPool-1 - Closing connection(无效连接被回收)或HikariPool-1 - Added connection(新连接创建)日志。
  • 连接池监控:通过 Spring Actuator 查看/actuator/metrics/hikaricp.connections.active(活跃连接数)是否下降,hikaricp.connections.idle(空闲连接数)是否上升。

4.2 搭建监控体系(预防复发)

  • 连接池监控:通过 Prometheus+Grafana 监控 HikariCP 指标(如activependingidle)。
  • 慢查询监控:使用pt-query-digest分析慢查询日志,定位高频慢 SQL(示例命令:pt-query-digest /var/log/mysql/slow.log > slow_report.txt)。
  • 事务监控:通过 APM 工具(如 SkyWalking)追踪事务耗时,识别超时事务。

五、总结:从 “救火” 到 “预防” 的完整闭环

通过 “临时终止→配置优化→代码修复→监控预防” 四步,可彻底解决长耗时进程引发的系统故障:

  1. 临时止血:手动终止 MySQL 长进程,快速恢复用户访问;通常无需重启 Tomcat,但需确保连接池配置正确。
  2. 配置优化:调整连接池与 MySQL 参数,避免连接耗尽与无效连接。
  3. 代码修复:修复连接泄露、控制事务超时,从根源减少长连接。
  4. 监控预防:通过日志与指标监控,提前发现慢查询与连接异常。

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

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

相关文章

SpringAI

机器学习: 定义:人工智能的子领域,通过数据驱动的方法让计算机学习规律,进行预测或决策。 核心方法: 监督学习(如线性回归、SVM)。 无监督学习(如聚类、降维)。 强化学…

lua 作为嵌入式设备的配置语言

从lua的脚本中获取数据 lua中栈的索引 3 | -1 2 | -2 1 | -3 可以在lua的解释器中加入自己自定的一些功能,其实没啥必要,就是为了可以练习下lua

ERP系统源码,小型工厂ERP系统源码,CRM+OA+进销存+财务

ERP系统源码,小型工厂ERP系统源码,ERP计划管理系统源码,CRMOA进销存财务 对于ERP来说,最为主要的作用就是能够强调企业的计划性,通过以业务订单以及客户的相关需求来作为企业计划的基础,并且还能够对企业现…

基于EFISH-SCB-RK3576/SAIL-RK3576的矿用本安型手持终端技术方案‌

(国产化替代J1900的矿山智能化解决方案) 一、硬件架构设计‌ ‌本安型结构设计‌ ‌防爆防护体系‌: 采用铸镁合金外壳复合防爆玻璃(抗冲击能量>20J),通过GB 3836.1-2021 Ex ib I Mb认证 全密闭IP68接口…

配置文件介绍xml、json

#灵感# 常用xml, 但有点模棱两可,记录下AI助理给我总结的。 .xml XML(eXtensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言。它与 HTML 类似,但有以下主要特点和用途&#xf…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-D. 扩展插件列表(PostGIS/PostgREST等)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 附录D. PostgreSQL扩展插件速查表一、插件分类速查表二、核心插件详解三、安装与配置指南四、应用场景模板五、版本兼容性说明六、维护与优化建议七、官方资源与工具八、附录…

Qt笔记---》.pro中配置

文章目录 1、概要1.1、修改qt项目的中间文件输出路径和部署路径1.2、Qt 项目模块配置1.3、外部库文件引用配置 1、概要 1.1、修改qt项目的中间文件输出路径和部署路径 (1)、为解决 “ 输出文件 ” 和 “ 中间输出文件 ”全部在同一个文件夹下的问题&am…

【Liblib】基于LiblibAI自定义模型,总结一下Python开发步骤

一、前言 Liblib AI(哩布哩布 AI)是一个集成了先进人工智能技术和用户友好设计的 AI 图像创作绘画平台和模型分享社区。 强大的图像生成能力 :以 Stable Diffusion 技术为核心,提供文生图、图生图、图像后期处理等功能&#xff…

CCF第七届AIOps国际挑战赛季军分享(RAG)

分享CCF 第七届AIOps国际挑战赛的季军方案,从我们的比赛经历来看,并不会,相反,私域领域问答的优秀效果说明RAG真的很重要 历经4个月的时间,从初赛赛道第1,复赛赛道第2,到最后决赛获得季军&…

【Cesium入门教程】第七课:Primitive图元

Cesium丰富的空间数据可视化API分为两部分:primitive API面向三维图形开发者,更底层一些。 Entity API是数据驱动更高级一些。 // entity // 调用方便,封装完美 // 是基于primitive的封装// primitive // 更接近底层 // 可以绘制高级图形 /…

【5分钟学Docker】Docker快速使用

目录 1. 概述 2. 基本操作 2.1. 镜像操作 2.2. 容器操作 2.3. 运行操作 2.4. 镜像保存 2.5. 镜像分享 3. 高级操作 4. 挂载 4.1. 目录挂载 4.2. 卷映射 1. 概述 Docker 镜像有镜像名称和TAG 2. 基本操作 2.1. 镜像操作 查看镜像 docker images docker image ls …

opencv 一些简单的设置

输出当前程序启动的路径 可能会出现 🔧 设置 C17 标准(解决 std::filesystem 报错) 在 VS 中,右键项目 → 属性。 选择左边的 “C/C” → “语言” 找到 C语言标准(C Language Standard)选项。 设置为&…

监控易运维管理软件:架构稳健,组件强大

在当今的信息化时代,运维管理对于企业的稳定运营至关重要。一款好的运维管理软件,不仅能够帮助企业高效管理IT基础设施,还能提升运维效率,降低运维成本。今天,我要给大家介绍的,就是我们公司自主研发的监控…

数字IC后端零基础入门基础理论(Day2)

数字IC后端零基础入门基础理论(Day1) Placement Blockage: cell摆放阻挡层。它是用来引导工具做placement的一种物理约束或手段,目的是希望工具按照我们的要求来做标准单元的摆放。 它主要有三种类型,分别是hard placement bloc…

零成本打造专属AI图像处理平台:IOPaint本地部署与远程访问指南

文章目录 前言1.什么是IOPaint?2.本地部署IOPaint3.IOPaint简单实用4.公网远程访问本地IOPaint5.内网穿透工具安装6.配置公网地址7.使用固定公网地址远程访问总结 前言 移动摄影的普及使得记录生活变得轻而易举,然而获得一张高质量的照片往往需要付出不…

操作系统-物理结构

操作系统使用read系统调用,将逻辑地址转(对于用户来说逻辑地址容易计算,因为各个逻辑块都相邻)成了逻辑块号和块内偏移量,并根据分配存储方式,将逻辑块号转成物理块号和块内偏移量 对于用户来说的文件的一…

《AI大模型应知应会100篇》第64篇:构建你的第一个大模型 Chatbot

第64篇:构建你的第一个大模型 Chatbot 手把手教你从零开始搭建一个基于大模型的聊天机器人 摘要 你是否想过,自己也能构建一个像 ChatGPT 一样能对话、能思考的聊天机器人(Chatbot)?别担心,这并不需要你是…

STM32 片上资源之串口

STM32 片上资源之串口 1 串口介绍1.1 初步介绍1.2 主要特性1.2.1 USART特性1.2.2 UART特性 1.3 主要寄存器1.4 波特率计算1.5 常用工作模式1.5.1 轮询模式:1.5.2 中断模式:1.5.3 DMA模式: 1.6 常见应用1.7 注意事项 2 软件层面协议2.1 基本概…

职坐标IT培训:互联网行业核心技能精讲

在互联网行业高速迭代的今天,掌握全链路核心技能已成为职业发展的关键突破口。职坐标IT培训聚焦行业需求,系统拆解从需求分析到系统部署的完整能力模型,助力从业者构建多维竞争力。无论是产品岗的用户调研与原型设计,还是技术岗的…

FlashInfer - 介绍 LLM服务加速库 地基的一块石头

FlashInfer - 介绍 LLM服务加速库 地基的一块石头 flyfish 大型语言模型服务中的注意力机制 大型语言模型服务(LLM Serving)迅速成为重要的工作负载。Transformer中的算子效率——尤其是矩阵乘法(GEMM)、自注意力(S…