docs: 添加问题10 HikariMonitorConfig空指针异常到问题清单
This commit is contained in:
parent
39db7c8b7a
commit
d11ed1ba1e
@ -19,6 +19,7 @@
|
||||
| 7 | 全链路追踪 | TraceContextHolder未在HTTP入口初始化导致链路断裂 | 高 | 已解决 |
|
||||
| 8 | OpenFeign配置 | FeignClient硬编码URL导致Nacos服务发现失效 | 高 | 已解决 |
|
||||
| 9 | Nacos 配置 | Nacos 3.0 客户端缺少 username/password 认证配置 | 高 | 已解决 |
|
||||
| 10 | 连接池监控 | HikariMonitorConfig空指针异常 | 中 | 已解决 |
|
||||
|
||||
---
|
||||
|
||||
@ -594,6 +595,77 @@ curl http://localhost:8000/sys/api/v1/sys/health
|
||||
|
||||
---
|
||||
|
||||
### 问题 10:HikariMonitorConfig 空指针异常
|
||||
|
||||
#### 问题现象
|
||||
服务启动后,定时任务日志中持续报错:
|
||||
```
|
||||
java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBean.getActiveConnections()" because the return value of "com.zaxxer.hikari.HikariDataSource.getHikariPoolMXBean()" is null
|
||||
at com.fundplatform.sys.config.HikariMonitorConfig.monitorHikariPool(HikariMonitorConfig.java:38)
|
||||
```
|
||||
|
||||
#### 问题原因
|
||||
**HikariCP 连接池初始化时机问题**:
|
||||
- `HikariDataSource.getHikariPoolMXBean()` 方法在连接池尚未初始化时返回 `null`
|
||||
- 定时任务在应用启动后立即执行,此时连接池可能还未完成初始化
|
||||
- 直接调用 `getActiveConnections()` 等方法会导致空指针异常
|
||||
|
||||
**相关代码**:
|
||||
```java
|
||||
// 问题代码
|
||||
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
|
||||
public void monitorHikariPool() {
|
||||
if (dataSource instanceof HikariDataSource) {
|
||||
HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
|
||||
// 未检查 getHikariPoolMXBean() 返回值是否为 null
|
||||
log.info("活跃连接数: {}", hikariDataSource.getHikariPoolMXBean().getActiveConnections());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 解决方案
|
||||
|
||||
**修复后代码**:
|
||||
```java
|
||||
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
|
||||
public void monitorHikariPool() {
|
||||
if (dataSource instanceof HikariDataSource) {
|
||||
HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
|
||||
HikariConfigMXBean config = hikariDataSource.getHikariConfigMXBean();
|
||||
var poolMXBean = hikariDataSource.getHikariPoolMXBean();
|
||||
|
||||
// 检查连接池是否已初始化
|
||||
if (poolMXBean == null) {
|
||||
log.debug("HikariCP 连接池尚未初始化,跳过监控");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("=== HikariCP 连接池状态 ===");
|
||||
log.info("连接池名称: {}", config.getPoolName());
|
||||
log.info("活跃连接数: {}", poolMXBean.getActiveConnections());
|
||||
log.info("空闲连接数: {}", poolMXBean.getIdleConnections());
|
||||
log.info("等待获取连接的线程数: {}", poolMXBean.getThreadsAwaitingConnection());
|
||||
log.info("最大连接数: {}", config.getMaximumPoolSize());
|
||||
log.info("最小空闲连接数: {}", config.getMinimumIdle());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**修复要点**:
|
||||
1. 先获取 `HikariPoolMXBean` 实例并存储到变量
|
||||
2. 检查是否为 `null`,为 `null` 则跳过本次监控
|
||||
3. 使用变量访问连接池信息,避免重复调用 `getHikariPoolMXBean()`
|
||||
|
||||
#### 修复文件
|
||||
- `fund-sys/src/main/java/com/fundplatform/sys/config/HikariMonitorConfig.java`
|
||||
|
||||
#### 经验总结
|
||||
- **调用可能返回 null 的方法前必须做空值检查**
|
||||
- **定时任务执行时需考虑资源初始化时机**,不能假设资源已就绪
|
||||
- **使用变量存储对象引用**,避免重复调用 getter 方法
|
||||
|
||||
---
|
||||
|
||||
## 预防措施清单
|
||||
|
||||
### 前后端接口对接
|
||||
@ -624,6 +696,7 @@ curl http://localhost:8000/sys/api/v1/sys/health
|
||||
| TraceId 传递 | ContextInterceptor 必须提取并设置 TraceId |
|
||||
| **FeignClient 配置** | **有注册中心时必须移除 url 属性,仅保留 name** |
|
||||
| **Nacos 3.0 认证** | **客户端必须配置 username 和 password(默认都是 nacos)** |
|
||||
| **定时任务资源检查** | **定时任务访问资源前需检查资源是否已初始化(如连接池)** |
|
||||
|
||||
### 功能开发流程
|
||||
|
||||
@ -675,6 +748,7 @@ curl http://localhost:8000/sys/api/v1/sys/health
|
||||
| `TraceId 链路断裂` | ContextInterceptor 未提取 TraceId | 在 preHandle 中添加 TraceId 设置逻辑 |
|
||||
| `服务发现失效` | FeignClient 硬编码 URL | 移除 url 属性,仅保留 name 使用 Nacos 发现 |
|
||||
| `Nacos 注册失败 (认证错误)` | 缺少 username/password 配置 | 在 discovery 节点添加 username 和 password |
|
||||
| `HikariPoolMXBean NullPointerException` | 定时任务执行时连接池未初始化 | 添加 poolMXBean 空值检查 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user