当前位置: 首页 > news >正文

Mysql的CommunicationsException

一、报错内容

com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 1,500,378 milliseconds ago.  
The last packet sent successfully to the server was 1,500,378 milliseconds ago. is longer than the server configured value of 'wait_timeout'. 
You should consider either expiring and/or testing connection validity before use in your application, 
increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

二、报错解释

客户端和 MySQL 数据库的连接由于长时间没有使用而超时断开。

逐句分析:

1、The last packet successfully received from the server was 1,500,378 milliseconds ago.
表示上次从服务器接收到的成功数据包已经过去了 1,500,378 毫秒(约25分钟),即在过去的这段时间里没有任何通信发生。

2、The last packet sent successfully to the server was 1,500,378 milliseconds ago.
说明上一次向服务器成功发送数据包的时间也是 1,500,378 毫秒前。也就是说,客户端与数据库的连接在过去 25 分钟内没有任何活动。

3、wait_timeout
这个报错提到 wait_timeout 是 MySQL 的一个配置项,表示数据库允许空闲连接保持的最大时间。如果超过这个时间没有任何通信,MySQL 就会自动关闭这个连接。你的连接可能因为空闲时间过长,超过了 wait_timeout 的配置值而被断开。

三、解决方案

1、重启服务,重置数据库连接。

2、增加 MySQL 的 wait_timeout 配置值:你可以在 MySQL 服务器的配置文件中增加 wait_timeout 的值,以允许连接保持更长的时间不被断开,我这边配置的是15分钟。

3、使用 autoReconnect=true:MySQL Connector/J 提供了 autoReconnect=true 的配置项,启用后,在连接断开时,会自动重新连接数据库,这样可以避免因为连接超时导致的错误。

4、当使用连接池连接数据库时,如果是druid连接池,通过配置druid.connectionErrorRetryAttempts来设置重试次数,从而实现连接的重置。

四、结论

应用服务基于数据库连接池和数据库之间建立的连接,存在心跳检测和存活状态检测,无论是客户端还是Mysql服务端都会在检测失败之后将连接关闭。当Mysql基于wait_time判断连接并关闭连接后,在客户端的连接池视角中,连接处于无效状态。如果此时有请求进来并获取连接时,如果获取的是无效的连接,将会基于CommunicationsException异常报错提示出来。

五、深入分析

以下内容均基于druid连接池进行说明。

为什么数据库就不能识别出来连接无效,并自动重试呢?其实连接池是支持这种配置的,只是默认是关闭。

5.1、检测无效连接

对于空闲线程可以基于如下配置进行检测

# 启用空闲连接检测机制
druid.testWhileIdle = true
druid.testOnBorrow = false  # 默认关闭。获取连接时是否检测连接有效性(影响性能)
druid.testOnReturn = false  # 默认关闭。归还连接时是否检测连接有效性(影响性能)

就像上面说的,如果每次获取连接时都进行有效性检测,将会带来性能的消耗,本身连接池就是提效的,每次都检查,性能必然有下降。

5.2、自动重试机制

# 当连接失败时,自动尝试重连
druid.connectionErrorRetryAttempts = 3  # 连接失败时的重试次数
druid.breakAfterAcquireFailure = true   # 是否在重试失败后关闭数据源,默认是关闭的

这个配置可以加,不过默认是没配置的。

5.3、回收无效连接

# 空闲连接检测时间间隔
druid.timeBetweenEvictionRunsMillis = 60000  # 60秒执行一次检测
druid.minEvictableIdleTimeMillis = 300000    # 连接空闲超过 5 分钟就进行回收

注意:minEvictableIdleTimeMillis 只对 minIdle(最小空闲连接数) 外的连接生效。

  • minIdle 的连接数大于 minEvictableIdleTimeMillis 设定的空闲时间时,连接池不会立即移除这些空闲连接。minIdle 确保了空闲连接的数量,而 minEvictableIdleTimeMillis 则决定哪些连接可以被清理。

  • 如果空闲连接数量已经达到 minIdle,且某些空闲连接的空闲时间超过了 minEvictableIdleTimeMillis,这些连接会被清理,而连接池将根据 minIdle 的要求重新创建新的连接以补充空闲连接数量。

同时Mysql的wait_time对所有连接都生效。所以会出现当应用流量较小时,最小空闲连接会被无效,但是没办法被回收,所以还是需要依赖重试机制。

http://www.lryc.cn/news/462494.html

相关文章:

  • C++学习笔记----9、发现继承的技巧(二)---- 重用目的的继承
  • 锐评 Nodejs 设计模式 - 创建与结构型
  • 【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制
  • 15分钟学Go 第4天:Go的基本语法
  • 【Qt】Qt的介绍——Qt的概念、使用Qt Creator新建项目、运行Qt项目、纯代码方式、可视化操作、认识对象模型(对象树)
  • 论文笔记:PTR: Prompt Tuning with Rules for Text Classification
  • 服务器和中转机协同工作以提高网络安全
  • Java利用itextpdf实现pdf文件生成
  • 2010年国赛高教杯数学建模C题输油管的布置解题全过程文档及程序
  • datawhale大模型bot应用开发--task3:工作流
  • 期货配资系统风控逻辑开发/完整源代码
  • 汽车免拆诊断案例 | 2023款零跑C01纯电车后备厢盖无法电动打开和关闭
  • 分布式存储架构 与分布式一致性协议
  • Unity Apple Vision Pro 保姆级开发教程 - Simulator 模拟器使用
  • Vue 之 插件与组件的区别
  • 了解 ChatGPT 中的公平性问题
  • 【PHP】安装swoole时报错:No package ‘libbrotlienc‘ found
  • postgresql执行计划解读案例
  • Matlab实现粒子群优化算法优化随机森林算法模型 (PSO-RF)(附源码)
  • 使用 EasyExcel 相邻数据相同时行和列的合并,包括动态表头、数据
  • 985研一学习日记 - 2024.10.16
  • 安装mysql 5.5.62
  • AnaTraf | 网络性能监控系统的价值
  • 决策树和集成学习的概念以及部分推导
  • servlet基础与环境搭建(idea版)
  • 【10月最新】植物大战僵尸杂交版新僵尸预告(附最新版本下载链接)
  • 网络编程-UDP以及数据库mysql
  • ubuntu 20.04 安装ros1
  • ShardingSphere-Proxy 数据库中间件MySql分库分表环境搭建
  • Pytest+selenium UI自动化测试实战实例