From 11d30d40b08884057a8aa142e03ab2e4f238fc07 Mon Sep 17 00:00:00 2001 From: cst61 Date: Wed, 15 Apr 2026 16:13:35 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=9F=E6=88=B7=E7=AE=A1=E7=90=86=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HikariCP连接池问题分析.md | 152 ------------------ .../java/com/cst/douyi/VideoHotUtil01.java | 4 + 2 files changed, 4 insertions(+), 152 deletions(-) delete mode 100644 HikariCP连接池问题分析.md create mode 100644 src/test/java/com/cst/douyi/VideoHotUtil01.java diff --git a/HikariCP连接池问题分析.md b/HikariCP连接池问题分析.md deleted file mode 100644 index d891cc5..0000000 --- a/HikariCP连接池问题分析.md +++ /dev/null @@ -1,152 +0,0 @@ -# HikariCP 连接池警告问题分析 - -## 问题现象 - -``` -WARN - HikariPool-Main - Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@xxx (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value. -WARN - HikariPool-Main - Thread starvation or clock leap detected (housekeeper delta=47s225ms20µs300ns). -``` - -## 问题原因分析 - -### 1. **连接已被MySQL服务器关闭** -- MySQL服务器端的 `wait_timeout` 参数可能比 HikariCP 的 `maxLifetime` 短 -- 或者由于网络问题、防火墙、负载均衡器等中间设备导致连接被关闭 -- 但 HikariCP 连接池还不知道连接已经失效,仍然尝试使用这些已关闭的连接 - -### 2. **maxLifetime 设置不当** -- **原配置**:`maxLifetime: 1800000` (30分钟) -- **问题**:如果 MySQL 的 `wait_timeout` 设置为更短的时间(比如1小时或更短),连接会在服务器端被关闭,但连接池还在使用 -- **最佳实践**:`maxLifetime` 应该设置为 MySQL `wait_timeout` 的 **70-80%** - -### 3. **keepaliveTime 不够频繁** -- **原配置**:`keepaliveTime: 300000` (5分钟) -- **问题**:5分钟才检测一次连接是否有效,如果连接在检测间隔内被关闭,连接池无法及时发现 -- **解决方案**:缩短到2-3分钟,更频繁地检测连接有效性 - -### 4. **JDBC URL 缺少连接参数** -- **原配置**:缺少 `socketTimeout`、`autoReconnect` 等参数 -- **影响**:无法及时检测到连接超时,无法自动重连 - -### 5. **线程饥饿或时钟跳跃** -- 系统负载过高导致 housekeeper 线程无法及时执行 -- 或者系统时钟发生跳跃(NTP同步、时区变更等) - -## 解决方案 - -### 已实施的配置优化 - -1. **缩短 maxLifetime** - ```yaml - maxLifetime: 900000 # 从30分钟缩短到15分钟 - ``` - -2. **缩短 keepaliveTime** - ```yaml - keepaliveTime: 120000 # 从5分钟缩短到2分钟 - ``` - -3. **优化 JDBC URL** - ```yaml - url: jdbc:mysql://...?socketTimeout=60000&connectTimeout=30000&autoReconnect=true&failOverReadOnly=false&maxReconnects=3&initialTimeout=2 - ``` - -### 建议的进一步检查 - -#### 1. 检查 MySQL wait_timeout 设置 - -连接到 MySQL 服务器,执行以下SQL查询: - -```sql -SHOW VARIABLES LIKE 'wait_timeout'; -SHOW VARIABLES LIKE 'interactive_timeout'; -``` - -**建议**: -- 如果 `wait_timeout` 是 28800 秒(8小时,MySQL默认值),`maxLifetime` 可以设置为 4-6 小时 -- 如果 `wait_timeout` 是 3600 秒(1小时),`maxLifetime` 应该设置为 45 分钟(2700000ms) -- 如果 `wait_timeout` 是 1800 秒(30分钟),`maxLifetime` 应该设置为 15 分钟(900000ms) - -#### 2. 监控连接池状态 - -可以启用 HikariCP 的 JMX 监控来观察连接池状态: - -```yaml -hikari: - registerMbeans: true # 启用JMX注册 -``` - -然后通过 JConsole 或类似工具监控连接池。 - -#### 3. 检查系统资源 - -- 检查系统 CPU 和内存使用情况 -- 检查是否有线程阻塞 -- 检查系统时钟是否同步(NTP) - -#### 4. 网络检查 - -- 检查应用服务器到数据库服务器的网络延迟 -- 检查是否有防火墙或负载均衡器在中间 -- 检查是否有网络中断或超时 - -## 配置参数说明 - -| 参数 | 原值 | 新值 | 说明 | -|------|------|------|------| -| `maxLifetime` | 1800000ms (30分钟) | 900000ms (15分钟) | 连接最大生存时间,应小于 MySQL wait_timeout 的 70-80% | -| `keepaliveTime` | 300000ms (5分钟) | 120000ms (2分钟) | 定期发送 keepalive 查询的间隔,用于检测连接是否有效 | -| JDBC URL | 缺少参数 | 添加 socketTimeout、autoReconnect 等 | 增强连接管理和自动重连能力 | - -## 预期效果 - -实施这些优化后,应该能够: -1. ✅ 更早地检测到已关闭的连接 -2. ✅ 避免使用无效连接导致的错误 -3. ✅ 减少连接验证失败的警告 -4. ✅ 提高连接池的稳定性和可靠性 - -## 注意事项 - -1. **maxLifetime 不能设置得太短**:如果设置得太短(比如5分钟),会导致连接频繁创建和销毁,影响性能 -2. **keepaliveTime 不能设置得太频繁**:如果设置得太频繁(比如30秒),会增加数据库负载 -3. **需要根据实际环境调整**:不同的 MySQL 配置和网络环境可能需要不同的参数值 - -## 参考文档 - -- [HikariCP 官方文档](https://github.com/brettwooldridge/HikariCP) -- [MySQL wait_timeout 说明](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_wait_timeout) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/java/com/cst/douyi/VideoHotUtil01.java b/src/test/java/com/cst/douyi/VideoHotUtil01.java new file mode 100644 index 0000000..ff5da5c --- /dev/null +++ b/src/test/java/com/cst/douyi/VideoHotUtil01.java @@ -0,0 +1,4 @@ +package com.cst.douyi; + +public class VideoHotUtil01 { +}