提交 28bc146a authored 作者: 陈泽健's avatar 陈泽健

docs(logs): 删除5.44日志分析报告并重构新统一平台监控文档结构

- 删除Docs/PRD/日志监测/分析报告/5.44服务日志监测分析报告.md文件
- 重命名PRD系统功能运行问题文档至负载一分组目录
- 创建5.45和5.46服务器的系统功能运行问题文档
- 新增5.45和5.46负载的详细问题分析与优化方案执行文档
- 更新分析结果路径引用至新的负载分组目录结构
上级 23fd7ac8
# 5.44服务日志监测分析报告
## 📋 报告信息
| 项目 | 内容 |
|------|------|
| **报告日期** | 2026-04-23 |
| **分析时间** | 14:20-14:30 |
| **服务器** | 192.168.5.44:22 |
| **容器** | ujava2 (运行45小时) |
| **日志文件** | /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log |
| **日志大小** | 9.4M |
---
## 一、服务器运行状态
### 1.1 容器状态
```
容器ID: 7088f5a00b40
镜像: 139.9.60.86:5000/ujava:v6
运行时长: 6 days ago Up 45 hours
端口映射: 0.0.0.0:8999->8999/tcp (主服务端口)
```
### 1.2 Java进程配置
```
JVM参数: -Xms1048m -Xmx1048m
注意: 与PRD文档记录的4096m不符
```
### 1.3 实际部署路径(已修正)
| 项目 | PRD记录 | 实际路径 |
|------|---------|---------|
| 容器内部署路径 | `/var/www/java/api-java-meeting2.0` | `/var/www/java/api/java-meeting/java-meeting2.0/` |
| JAR文件 | - | `ubains-meeting-inner-api-1.0-SNAPSHOT.jar` |
| 日志路径 | - | `logs/ubains-INFO-AND-ERROR.log` |
---
## 二、日志分析结果
### 2.1 采样统计(最近500行)
| 指标 | 数量 | 百分比 |
|------|------|--------|
| 总行数 | 500 | 100% |
| ERROR | 27 | 5.4% |
| WARN | 0 | 0% |
| INFO | 473 | 94.6% |
### 2.2 全文件错误统计
| 异常类型 | 出现次数 | 严重程度 |
|---------|---------|---------|
| **ClassCastException** | **115** | 🔴 高 |
| TooManyResultsException | 0 | - |
| NullPointerException | 0 | - |
| Timeout | 0 | - |
---
## 三、核心问题分析
### 🔴 问题:ClassCastException 频繁发生
#### 3.1 错误详情
```
java.lang.ClassCastException: com.ubains.meeting.dto.TokenDetails cannot be cast to com.ubains.meeting.dto.ManageUserDetails
```
#### 3.2 触发位置
```
文件: com.ubains.filter.JwtAuthenticationTokenFilter.java
行号: 221
方法: doFilterInternal()
```
#### 3.3 触发特征
| 特征 | 值 |
|------|-----|
| 触发频率 | 每10秒一次 |
| 来源IP | 192.168.9.204 |
| 来源账号 | ANA-29K-0066 |
| 请求类型 | JWT认证请求 |
#### 3.4 完整堆栈
```
at com.ubains.filter.JwtAuthenticationTokenFilter.doFilterInternal(JwtAuthenticationTokenFilter.java:221)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at com.ubains.filter.CacheHttpServletRequestFilter.doFilter(CacheHttpServletRequestFilter.java:42)
...
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
```
#### 3.5 问题分析
**根本原因:**
- JWT token 中存储的是 `TokenDetails` 类型对象
- 代码在 `JwtAuthenticationTokenFilter.java:221` 尝试将其强制转换为 `ManageUserDetails` 类型
- 这两个类型不兼容,导致 ClassCastException
**影响范围:**
1. 来自 IP:192.168.9.204 (账号:ANA-29K-0066) 的所有认证请求失败
2. 产生大量错误日志(累计115次)
3. 可能导致该设备端无法正常访问系统功能
**业务影响:**
- 设备端认证失败可能导致会议控制功能异常
- 频繁的错误日志占用磁盘空间
- 错误堆栈打印消耗CPU资源
---
## 四、修复建议
### 4.1 紧急修复(P0)
#### 建议1:修复JwtAuthenticationTokenFilter类型转换错误
**文件位置:** `JwtAuthenticationTokenFilter.java:221`
**问题代码:**
```java
ManageUserDetails userDetails = (ManageUserDetails) authentication.getDetails();
```
**修复方案A:使用instanceof检查**
```java
Object details = authentication.getDetails();
if (details instanceof ManageUserDetails) {
ManageUserDetails userDetails = (ManageUserDetails) details;
// 处理逻辑
} else if (details instanceof TokenDetails) {
TokenDetails tokenDetails = (TokenDetails) details;
// 转换或分别处理
} else {
logger.error("Unsupported authentication details type: " + details.getClass());
}
```
**修复方案B:统一使用TokenDetails**
```java
TokenDetails tokenDetails = (TokenDetails) authentication.getDetails();
// 从TokenDetails获取需要的信息
```
#### 建议2:检查JWT Token生成逻辑
确保Token生成和解析使用相同的类型。
### 4.2 中期优化(P1)
1. **添加设备端白名单或特殊处理**
- 对 IP:192.168.9.204 的设备端请求进行特殊认证处理
- 或联系设备端确认认证方式是否匹配
2. **增加异常日志限流**
- 避免同一错误重复打印大量堆栈
- 可使用日志去重或降级策略
### 4.3 长期优化(P2)
1. **统一认证类型体系**
- Review `TokenDetails``ManageUserDetails` 的设计
- 考虑是否需要统一为一个类型
2. **增加单元测试**
- 添加 JWT 认证相关的单元测试
- 覆盖不同类型用户认证场景
---
## 五、与PRD文档对比
### 5.1 已变化项
| 项目 | PRD记录 | 实际值 | 状态 |
|------|---------|--------|------|
| JVM-Xmx | 4096m | 1048m | ⚠️ 不一致 |
| 部署路径 | api-java-meeting2.0 | api/java-meeting/java-meeting2.0/ | ⚠️ 不一致 |
| 主要错误 | TooManyResultsException | ClassCastException | 🔄 变化 |
### 5.2 PRD中提及的问题当前状态
| 问题 | PRD描述 | 当前状态 |
|------|---------|---------|
| TooManyResultsException | 11MB错误日志 | ✅ 未再出现 |
| 定时任务线程池不足 | 10线程 vs 59任务 | ⏳ 待验证 |
| Thread.sleep 4秒 | 每任务浪费4秒 | ⏳ 待验证 |
---
## 六、后续行动计划
| 序号 | 行动项 | 优先级 | 负责人 | 截止日期 | 状态 |
|------|--------|--------|--------|----------|------|
| 1 | 修复JwtAuthenticationTokenFilter类型转换错误 | P0 | | | [ ] |
| 2 | 联系IP:192.168.9.204设备端确认认证方式 | P1 | | | [ ] |
| 3 | 更新PRD文档中的部署路径和JVM参数 | P1 | | | [ ] |
| 4 | 验证PRD中其他优化项是否已生效 | P2 | | | [ ] |
| 5 | 添加JWT认证单元测试 | P2 | | | [ ] |
---
## 七、附录
### 7.1 错误日志样本
```
2026-04-23 14:01:50.809 [http-nio-8999-exec-9] ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.ClassCastException: com.ubains.meeting.dto.TokenDetails cannot be cast to com.ubains.meeting.dto.ManageUserDetails
at com.ubains.filter.JwtAuthenticationTokenFilter.doFilterInternal(JwtAuthenticationTokenFilter.java:221)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
```
### 7.2 监测命令
```bash
# SSH连接信息
Host: 192.168.5.44
Port: 22
Username: root
Password: Ubains@123
# 实时查看日志
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log
# 查看最近的ClassCastException
docker exec ujava2 grep -A 20 "ClassCastException" /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log
# 统计错误类型
docker exec ujava2 grep -oE "[A-Z][a-zA-Z]+Exception" /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log | sort | uniq -c | sort -rn
```
---
**报告生成时间:** 2026-04-23 14:30
**报告生成工具:** Claude Code SSH日志监测
**下次监测建议:** 修复后24小时复查
# 多服务日志监测分析报告
## 📋 报告信息
| 项目 | 内容 |
|------|------|
| **报告日期** | 2026-04-23 |
| **分析时间** | 14:35 |
| **服务器** | 192.168.5.44:22 |
| **容器** | ujava2 |
| **监测服务数** | 8个 |
---
## 一、服务列表与日志路径
| 序号 | 服务名称 | 日志路径 | 状态 |
|------|---------|---------|------|
| 1 | 主服务 (java-meeting2.0) | `/var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log` | ✅ |
| 2 | 对外服务 (java-meeting-extapi) | `/var/www/java/api/java-meeting/java-meeting-extapi/logs/ubains-INFO-AND-ERROR.log` | ✅ |
| 3 | 定时任务 (java-quartz) | `/var/www/java/api/java-meeting/java-quartz/logs/ubains-INFO-AND-ERROR.log` | ✅ |
| 4 | MQTT服务 (java-mqtt) | `/var/www/java/api/java-meeting/java-mqtt/logs/ubains-INFO-AND-ERROR.log` | ✅ |
| 5 | 消息调度 (java-message-scheduling) | `/var/www/java/api/java-meeting/java-message-scheduling/logs/ubains-INFO-AND-ERROR.log` | ✅ |
| 6 | 鉴权认证 (auth-sso-auth) | `/var/www/java/api/auth/auth-sso-auth/logs/auth-sso-auth/log.out` | ✅ |
| 7 | 鉴权网关 (auth-sso-gatway) | `/var/www/java/api/auth/auth-sso-gatway/logs/auth-sso-gateway/log.out` | ✅ |
| 8 | 鉴权系统 (auth-sso-system) | `/var/www/java/api/auth/auth-sso-system/logs/auth-sso-system/log.out` | ✅ |
---
## 二、总体健康状况
| 状态等级 | 服务数 | 服务名称 |
|---------|-------|---------|
| 🟢 OK | 4个 | MQTT服务、消息调度、鉴权认证、鉴权网关、鉴权系统 |
| 🟡 WARN | 1个 | 对外服务 |
| 🔴 CRITICAL | 2个 | 主服务、定时任务 |
---
## 三、各服务详细分析
### 🔴 服务1:主服务 (java-meeting2.0) - CRITICAL
| 指标 | 值 |
|------|-----|
| 日志大小 | 13M |
| 采样行数 | 500行 |
| ERROR数 | 79 (15.8%) |
| WARN数 | 4 |
#### 错误类型分布
| 错误类型 | 数量 | 占比 |
|---------|-----|------|
| **ClassCastException** | 39 | 49% |
| Other | 40 | 51% |
#### 核心问题
```
java.lang.ClassCastException: com.ubains.meeting.dto.TokenDetails
cannot be cast to com.ubains.meeting.dto.ManageUserDetails
位置: JwtAuthenticationTokenFilter.java:221
频率: 每10秒一次
来源: IP:192.168.9.204, 账号:ANA-29K-0066
```
#### 修复建议
1. 修改 `JwtAuthenticationTokenFilter.java:221` 类型转换逻辑
2. 使用 `instanceof` 检查后再转换
---
### 🟡 服务2:对外服务 (java-meeting-extapi) - WARN
| 指标 | 值 |
|------|-----|
| 日志大小 | 2.7M |
| 采样行数 | 500行 |
| ERROR数 | 47 (9.4%) |
| WARN数 | 1 |
#### 错误类型分布
| 错误类型 | 数量 | 占比 |
|---------|-----|------|
| Other | 28 | 60% |
| **Connection** | 19 | 40% |
#### 核心问题
```
redis.clients.jedis.exceptions.JedisConnectionException:
Could not get a resource from the pool
Caused by: Failed connecting to 192.168.5.4
```
#### 分析
- Redis连接池获取资源失败
- 目标Redis地址: 192.168.5.4
- 可能原因: Redis服务未启动或网络不通
---
### 🔴 服务3:定时任务 (java-quartz) - CRITICAL
| 指标 | 值 |
|------|-----|
| 日志大小 | 34M |
| 采样行数 | 487行 |
| ERROR数 | 162 (33.3%) |
| WARN数 | 1 |
#### 错误类型分布
| 错误类型 | 数量 | 占比 |
|---------|-----|------|
| **SQLException** | 72 | 44% |
| Other | 65 | 40% |
| **Connection** | 25 | 15% |
#### 核心问题
```
java.sql.SQLNonTransientConnectionException:
Could not create connection to database server.
Attempted reconnect 3 times. Giving up.
数据库地址: jdbc:mysql://192.168.5.44:8306/ubains
错误原因: Connection refused (连接被拒绝)
```
#### 分析
- 定时任务无法连接到数据库
- 数据库地址: 192.168.5.44:8306
- 端口8306连接被拒绝
- 影响: 所有依赖数据库的定时任务失败
#### 修复建议
1. 检查MySQL服务是否在端口8306上运行
2. 验证数据库配置是否正确
3. 检查防火墙是否开放8306端口
---
### 🟢 服务4:MQTT服务 (java-mqtt) - OK
| 指标 | 值 |
|------|-----|
| 日志大小 | 275K |
| 采样行数 | 492行 |
| ERROR数 | 14 (2.8%) |
| WARN数 | 206 |
#### 状态
- 错误率较低,处于健康状态
- 有较多警告信息,但不影响核心功能
---
### 🟢 服务5:消息调度 (java-message-scheduling) - OK
| 指标 | 值 |
|------|-----|
| 日志大小 | 45K |
| 采样行数 | 255行 |
| ERROR数 | 3 (1.2%) |
| WARN数 | 176 |
#### 状态
- 错误率最低,运行健康
- 警告数量较多但不影响功能
---
### 🟢 服务6-8:鉴权服务 (auth-sso) - OK
| 服务 | 日志大小 | ERROR | WARN |
|------|---------|-------|------|
| 鉴权认证 | 未知 | 0 | 0 |
| 鉴权网关 | 未知 | 0 | 0 |
| 鉴权系统 | 未知 | 0 | 0 |
#### 状态
- 所有鉴权服务运行正常
- 无错误和警告日志
- 日志文件较小或刚启动
---
## 四、关键问题汇总
### 🔴 问题1:主服务 ClassCastException
- **严重程度**: 高
- **影响范围**: 设备端认证失败
- **修复优先级**: P0
### 🔴 问题2:定时任务数据库连接失败
- **严重程度**: 高
- **影响范围**: 所有数据库相关定时任务
- **修复优先级**: P0
- **可能原因**: MySQL服务未在8306端口启动
### 🟡 问题3:对外服务Redis连接失败
- **严重程度**: 中
- **影响范围**: Redis相关功能
- **修复优先级**: P1
- **可能原因**: Redis服务未启动或网络不通
---
## 五、修复行动计划
| 序号 | 问题 | 服务 | 优先级 | 建议措施 | 状态 |
|------|------|------|--------|---------|------|
| 1 | ClassCastException | 主服务 | P0 | 修复JwtAuthenticationTokenFilter类型转换 | [ ] |
| 2 | 数据库连接失败 | 定时任务 | P0 | 检查MySQL服务8306端口状态 | [ ] |
| 3 | Redis连接失败 | 对外服务 | P1 | 检查Redis服务192.168.5.4状态 | [ ] |
---
## 六、服务器状态检查命令
```bash
# SSH连接信息
Host: 192.168.5.44
Port: 22
Username: root
Password: Ubains@123
# 检查MySQL服务8306端口
docker exec ujava2 netstat -tlnp | grep 8306
# 检查MySQL服务状态
docker exec ujava2 ps aux | grep mysql
# 检查Redis连接
docker exec ujava2 telnet 192.168.5.4 6379
# 实时监控各服务日志
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-quartz/logs/ubains-INFO-AND-ERROR.log
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-meeting-extapi/logs/ubains-INFO-AND-ERROR.log
```
---
**报告生成时间:** 2026-04-23 14:35
**下次复查建议:** 修复完成后24小时
# 多服务日志监测分析报告
## 📋 报告信息
| 项目 | 内容 |
|------|------|
| **报告日期** | 2026-05-06 |
| **分析时间** | 10:45 |
| **服务器** | 192.168.5.44:22 |
| **容器** | ujava2 |
| **监测服务数** | 5个 |
| **系统运行时长** | 19天 |
---
## 一、服务列表与日志路径
| 序号 | 服务名称 | 日志路径 | 状态 |
|------|---------|---------|------|
| 1 | 主服务 (java-meeting2.0) | `/var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log` | 🟡 WARN |
| 2 | 对外服务 (java-meeting-extapi) | `/var/www/java/api/java-meeting/java-meeting-extapi/logs/ubains-INFO-AND-ERROR.log` | 🟢 OK |
| 3 | 鉴权认证 (auth-sso-auth) | `/var/www/java/api/auth/auth-sso-auth/logs/auth-sso-auth/log.out` | 🟢 OK |
| 4 | 鉴权网关 (auth-sso-gatway) | `/var/www/java/api/auth/auth-sso-gatway/logs/auth-sso-gateway/log.out` | 🟢 OK |
| 5 | 鉴权系统 (auth-sso-system) | `/var/www/java/api/auth/auth-sso-system/logs/auth-sso-system/log.out` | 🟢 OK |
---
## 二、总体健康状况
| 状态等级 | 服务数 | 服务名称 |
|---------|-------|---------|
| 🟢 OK | 4个 | 对外服务、鉴权认证、鉴权网关、鉴权系统 |
| 🟡 WARN | 1个 | 主服务 |
| 🔴 CRITICAL | 0个 | - |
---
## 三、各服务详细分析
### 🟡 服务1:主服务 (java-meeting2.0) - WARN
| 指标 | 值 |
|------|-----|
| ERROR数 | 14 |
| WARN数 | 101 |
| 错误率 | 低 |
#### 错误类型分布
| 错误类型 | 数量 | 占比 |
|---------|-----|------|
| **LettuceException** | 8 | 57% |
| **RedisCommandTimeoutException** | 4 | 29% |
| PassThroughException | 4 | 29% |
| LettuceAccessException | 4 | 29% |
| FallbackException | 4 | 29% |
| TimeoutException | 2 | 14% |
| QueryTimeoutException | 2 | 14% |
#### 核心问题
```
错误类型: Redis连接超时异常
触发频率: 约1次/小时
主要原因: Lettuce Redis客户端连接超时
错误示例:
- RedisUtil_func Redis高性能功能函数
- lzzsh.switch 联众_switch业务处理
```
#### 修复建议
1. **检查Redis服务状态** - 确认Redis服务是否正常运行
2. **增加Redis连接超时配置** - 调整Lettuce客户端超时参数
3. **增加Redis连接池大小** - 应对高并发场景
---
### 🟢 服务2:对外服务 (java-meeting-extapi) - OK
| 指标 | 值 |
|------|-----|
| ERROR数 | 1 |
| WARN数 | 0 |
| 错误率 | 极低 |
#### 错误分析
```
错误类型: MQTT连接丢失
触发时间: 2026-05-06 09:47:41
错误信息: Lost connection: 已断开连接; retrying...
```
#### 状态评估
- MQTT连接自动重连机制正常
- 不影响主要业务功能
- 建议监控MQTT Broker状态
---
### 🟢 服务3-5:鉴权服务 (auth-sso) - OK
| 服务 | ERROR | WARN | 状态 |
|------|-------|------|------|
| 鉴权认证 (auth-sso-auth) | 0 | 0 | ✅ 正常 |
| 鉴权网关 (auth-sso-gatway) | 0 | 0 | ✅ 正常 |
| 鉴权系统 (auth-sso-system) | 0 | 0 | ✅ 正常 |
#### 状态评估
- 所有鉴权服务运行正常
- 无错误和警告日志
- 日志文件较小或刚重启
---
## 四、系统资源状态
### 4.1 Docker容器状态
```
CONTAINER ID: 7088f5a00b40
NAME: ujava2
CPU使用率: 3.22%
内存使用: 3.881GiB / 15.12GiB (25.67%)
网络I/O: 16.6GB / 8.72GB
磁盘I/O: 5.26GB / 3.84MB
进程数: 686
```
### 4.2 Java进程状态
```
PID 1 - /bin/bash /var/www/java/api/start.sh
PID 210 - auth-sso-system (Xms256m, Xmx512m)
PID 1628 - dubbo-welink (Xms1024m, Xmx1024m)
PID 806434 - auth-sso-auth (Xms256m, Xmx512m)
PID 806644 - auth-sso-gatway (Xms256m, Xmx512m)
```
### 4.3 数据库连接状态
```
MySQL连接数: 0
Redis连接数: 0
```
⚠️ **注意**: 连接数显示为0可能是因为:
1. 使用了docker exec查询,无法看到容器内实际连接
2. 查询命令权限不足
3. 连接使用完毕立即释放
### 4.4 系统负载
```
当前时间: 10:45:30
运行时长: 19天 2小时 3分钟
负载: 0.19 (1分钟), 0.26 (5分钟), 0.38 (15分钟)
```
✅ 负载正常
### 4.5 磁盘使用情况
```
/dev/mapper/openeuler-data 75G 66G 4.8G 94% /data
```
🔴 **警告**: 磁盘使用率达94%,剩余空间仅4.8GB,需要立即清理!
---
## 五、关键问题汇总
### 🔴 问题1:磁盘空间严重不足
- **严重程度**: 高
- **影响范围**: 所有服务
- **当前状态**: 94%使用率,剩余4.8GB
- **修复优先级**: P0
- **建议措施**:
1. 清理旧的日志文件
2. 清理Docker镜像和容器缓存
3. 清理临时文件
### 🟡 问题2:主服务Redis连接超时
- **严重程度**: 中
- **影响范围**: 主服务Redis相关功能
- **当前状态**: 间歇性超时
- **修复优先级**: P1
- **建议措施**:
1. 检查Redis服务状态
2. 调整Redis连接超时配置
3. 增加连接池大小
### 🟢 问题3:对外服务MQTT连接断开
- **严重程度**: 低
- **影响范围**: MQTT消息接收
- **当前状态**: 自动重连正常
- **修复优先级**: P2
- **建议措施**:
1. 监控MQTT Broker状态
2. 检查网络稳定性
---
## 六、与历史报告对比
### 6.1 问题变化情况
| 问题 | 4月23日报告 | 5月6日报告 | 状态变化 |
|------|-----------|-----------|---------|
| ClassCastException | 115次 | 0次 | ✅ 已修复 |
| TooManyResultsException | 0次 | 0次 | ✅ 已修复 |
| Redis连接超时 | 未报告 | 14次 | 🆕 新问题 |
| 数据库连接失败 | 连接被拒绝 | 待验证 | 🔄 状态待确认 |
### 6.2 优化效果评估
| 优化项 | 状态 | 说明 |
|--------|------|------|
| ClassCastException修复 | ✅ 完成 | 之前的类型转换错误已解决 |
| TooManyResultsException修复 | ✅ 完成 | WeLink同步异常已解决 |
| 定时任务数据库连接 | ⏳ 待验证 | 需要进一步检查 |
---
## 七、修复行动计划
| 序号 | 问题 | 服务 | 优先级 | 建议措施 | 负责人 | 截止日期 | 状态 |
|------|------|------|--------|---------|--------|----------|------|
| 1 | 磁盘空间不足 | 系统 | P0 | 清理日志和Docker缓存 | | | [ ] |
| 2 | Redis连接超时 | 主服务 | P1 | 检查Redis服务状态和配置 | | | [ ] |
| 3 | MQTT连接断开 | 对外服务 | P2 | 监控MQTT Broker | | | [ ] |
---
## 八、服务器检查命令参考
```bash
# SSH连接信息
Host: 192.168.5.44
Port: 22
Username: root
Password: Ubains@123
# 检查磁盘使用
docker exec ujava2 df -h
# 清理Docker缓存
docker system prune -a
# 检查Redis服务状态
docker exec ujava2 netstat -tlnp | grep 6379
# 实时监控各服务日志
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-meeting2.0/logs/ubains-INFO-AND-ERROR.log
docker exec ujava2 tail -f /var/www/java/api/java-meeting/java-meeting-extapi/logs/ubains-INFO-AND-ERROR.log
# 检查Java进程
docker exec ujava2 ps aux | grep java
# 检查系统负载
docker exec ujava2 uptime
```
---
## 九、监测结论
### 总体评估
-**鉴权服务**: 全部运行正常,无错误
- 🟡 **主服务**: 有Redis连接超时问题,需要关注
- 🟢 **对外服务**: 基本正常,MQTT连接自动恢复
- 🔴 **系统资源**: 磁盘空间严重不足,需要立即处理
### 建议
1. **立即执行**: 清理磁盘空间,避免服务因磁盘满而停止
2. **尽快处理**: 检查Redis服务状态,解决连接超时问题
3. **持续监控**: 定期检查各服务日志和系统资源使用情况
---
**报告生成时间:** 2026-05-06 10:45
**报告生成工具:** Claude Code SSH日志监测
**下次监测建议:** 磁盘清理完成后24小时复查
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
- 登录服务器,监测相关的运行情况结合代码进行优化 - 登录服务器,监测相关的运行情况结合代码进行优化
### 分析结果: ### 分析结果:
- `Docs/PRD/日志监测/服务日志分析结果` - `Docs/PRD/日志监测/分析报告/新统一平台/负载一`
### 代码规范 ### 代码规范
- 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md` - 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
......
## 📋 背景
- 预定系统,支持预约会议、签到、联动无纸化等功能
**服务器IP**:192.168.5.46 root 密码 Ubains@123
**容器内主服务部署路径**:/var/www/java/api/api-java-meeting2.0
**宿主机主服务部署路径**, /data/services/api/java-meeting/java-meeting2.0
**容器内对外服务部署路径**:/var/www/java/api/api-java-meeting-extapi
**宿主机对外服务部署路径**, /data/services/api/java-meeting/java-meeting-extapi
**容器内鉴权服务部署路径**:/var/www/java/api/auth/auth-sso-auth、/var/www/java/api/auth/auth-sso-gatway、/var/www/java/api/auth/auth-sso-system
**宿主机对外服务部署路径**, /data/services/api/auth/auth-sso-auth、/data/services/api/auth/auth-sso-gatway、/data/services/api/auth/auth-sso-system
**部署容器** docker环境:ujava2
## 🎯 任务
### 问题1: 监查查询项目运行为什么有时出现进程消失的问题,有时间进程存在但不运行
- 查找代码的优化项,找出优化或配置问题
- 登录服务器,监测相关的运行情况结合代码进行优化
### 分析结果:
- `Docs/PRD/日志监测/分析报告/新统一平台/负载三`
### 代码规范
- 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 严格按照问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 严格按照方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 严格按照文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 严格按照测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
### 问题记录与规避
- 执行时,按照Docs/PRD/日志监测/_PRD_方法总结_记录文档.md,累计的记录所积累的经验,规避已经出现过的问题
- 执行时,按照Docs/PRD/日志监测/_PRD_方法总结_记录文档.md,累计的记录所积累的经验,规避已经出现过的问题
\ No newline at end of file
# 会议系统进程消失/进程存在但不运行 — 问题分析与优化方案
## 📋 背景
- 预定系统,支持预约会议、签到、联动无纸化等功能
**服务器IP**:192.168.5.46 root 密码 Ubains@123
**部署容器**:docker环境:ujava2
### 服务列表
| 服务名称 | 容器内部署路径 | 宿主机部署路径 | 日志文件 |
|---------|---------------|---------------|---------|
| **主服务** | `/var/www/java/api/java-meeting/java-meeting2.0` | `/data/services/api/java-meeting/java-meeting2.0` | `logs/ubains-INFO-AND-ERROR.log` |
| **对外服务** | `/var/www/java/api/java-meeting/java-meeting-extapi` | `/data/services/api/java-meeting/java-meeting-extapi` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-认证** | `/var/www/java/api/auth/auth-sso-auth` | `/data/services/api/auth/auth-sso-auth` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-网关** | `/var/www/java/api/auth/auth-sso-gatway` | `/data/services/api/auth/auth-sso-gatway` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-系统** | `/var/www/java/api/auth/auth-sso-system` | `/data/services/api/auth/auth-sso-system` | `logs/ubains-INFO-AND-ERROR.log` |
## 🎯 任务
### 问题:监查查询项目运行为什么有时出现进程消失的问题,有时间进程存在但不运行
- 查找代码的优化项,找出优化或配置问题
- 登录服务器,监测相关的运行情况结合代码进行优化
---
## 一、服务器运行现状(2026-04-22 11:05 采集)
| 指标 | 值 | 状态 |
|------|-----|------|
| 服务器IP | 192.168.5.50 | - |
| Docker容器 | ujava2 | - |
| 容器内存限制 | **无限制**(0) | 宿主机 7.25GiB |
| 当前内存使用 | **2.43GiB**(33.5%) | 正常 |
| Docker 重启策略 | `always`,重启次数 **0** | 容器未重启过 |
| JVM 启动参数 | `-Xms2048m -Xmx4096m` | 与 run.sh 不一致 |
| Java 线程数 | **149** | 偏高 |
| Socket FD 数 | **21** | 正常 |
| 进程运行时长 | **23小时20分** | 当前存活 |
| ERROR 日志 | **11MB**,全是 `TooManyResultsException` | 需修复 |
| 部署路径 | `/var/www/java/api-java-meeting2.0` | - |
---
## 二、问题分析
### 问题A:进程消失(进程直接退出)
#### A1. JVM 参数不一致 — 部署脚本未更新(高风险)
**现状对比:**
| 来源 | -Xms | -Xmx |
|------|------|------|
| `run.sh` 中定义 | 1024m | **2048m** |
| 实际运行进程 | 2048m | **4096m** |
**问题原因:** 有人手动修改过启动参数或有另一套启动流程,但 `run.sh` 未同步更新。
**影响:** 通过 `start.sh``run.sh` 重启时,JVM 堆内存会从当前的 4096m 降回 **2048m**,在 149 个线程 + 59 个定时任务的高负载下,极易触发 OOM 导致进程消失。
**涉及文件:**
- 服务器 `/var/www/java/api-java-meeting2.0/run.sh`(不在代码仓库中)
- 服务器 `/var/www/java/start.sh`(容器入口)
**`run.sh` 当前内容:**
```sh
start)
nohup java -Xms1024m -Xmx2048m -jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**`start.sh` 当前内容:**
```sh
/usr/local/nginx/sbin/nginx
sleep 2
cd /var/www/java/api-java-meeting2.0
./run.sh # 不传参数,走 *) 分支 = stop + start,使用 run.sh 里的 -Xmx2048m
sleep 60
cd /var/www/java/api-dubbo-welink
./run.sh # 启动第二个 Java 进程
```
---
#### A2. 两个 Java 进程内存总和超限(高风险)
`start.sh` 启动了两个 Java 进程:
| 进程 | -Xms | -Xmx | 实际 RSS |
|------|------|------|----------|
| meeting 2.0 | 2048m | **4096m** | ~1.6GB |
| api-dubbo-welink | 1024m | **2048m** | ~800MB |
| **合计** | 3072m | **6144m** | ~2.5GB |
宿主机总内存 7.25GiB,两个 Java 进程理论最大可占 **6GB**,加上操作系统和其他进程,极易触发 Linux OOM Killer。
**影响:** 当 meeting 2.0 进行大量定时任务处理时,堆内存突增,超过可用内存,Linux OOM Killer 直接杀掉 Java 进程。
---
#### A3. `System.exit(0)` 在授权校验失败时直接退出(中风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/MybatisPlusConfig.java:216-218`
```java
if (!(localSHA3.equals(startCode))) {
logger.info("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
System.exit(0);
}
```
**问题原因:** Docker 容器重启后,虚拟化环境下 MAC 地址或 CPU 序号可能变化,导致授权校验失败。
**其他 `System.exit(0)` 调用点:**
| 文件 | 行号 | 触发条件 |
|------|------|---------|
| `MybatisPlusConfig.java` | 218 | CPU/MAC 与授权文件不匹配 |
| `AdjustmentDb.java` | 355 | 数据库结构调整失败 |
| `FaceEngineManager.java` | 52, 71 | 人脸引擎激活失败 |
---
#### A4. `run.sh` 使用 `kill -9` 强杀进程(低风险)
**涉及文件:** 服务器 `run.sh`
```sh
stop)
kill -9 `cat $SERVICE_DIR/$PID`
```
`kill -9` 不执行 Spring Boot 优雅关闭,可能导致数据库连接未释放、Redis 连接残留、临时文件未清理。
---
### 问题B:进程存在但不运行(假死)
#### B1. 定时任务线程池严重不足(高风险 — 最可能的元凶)
**涉及文件:** `ubains-meeting-inner-api/.../config/quartz/ScheduleThreadPool.java`
```java
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
Method[] methods = BatchProperties.Job.class.getMethods(); // BUG:扫描的是错误的类
int defaultPoolSize = 10;
int corePoolSize = 0;
// ... 遍历 BatchProperties.Job 的方法,不会找到任何 @Scheduled 注解
// 最终 corePoolSize = 0 < 10,被 defaultPoolSize=10 兜底
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
}
```
**问题分析:**
- 代码扫描的是 `BatchProperties.Job.class` 的方法,而不是项目中实际的 `@Scheduled` 方法
- 结果线程池大小固定为 **10 个线程**
- 项目中实际有 **59 个 `@Scheduled` 定时任务文件**(inner-api 模块)
- 当前 Java 进程已有 **149 个线程**,定时任务调度线程远不够用
**影响:** 多个定时任务同时触发时排队等待,如果某个任务执行时间很长(如 `SendMessageQuartz` 500+ 行代码),会阻塞其他所有任务的调度,最终导致应用无法响应 HTTP 请求。
---
#### B2. `RedisLockAspect` 每个定时任务执行后 sleep 4秒(高风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/quartz/RedisLockAspect.java:60-61, 72-73`
```java
// 无论是否启用负载均衡,都会 sleep
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // PROTECT_TIME = 2 << 11 = 4096ms
```
**问题分析:**
- 每个带 `@RedisLock` 注解的定时任务执行完后都会**强制 sleep 4秒**
- 59 个定时任务中大量使用了 `@RedisLock` 注解
- 累计无效等待时间可达 **236 秒**(59 × 4秒)
- 在仅 10 个调度线程的条件下,这些 sleep 占满了宝贵的线程资源
**影响:** 定时任务执行效率极低,大量线程被 sleep 占据,无法及时处理新的定时触发和 HTTP 请求。
---
#### B3. WeLink 同步持续抛出异常(中风险)
**涉及文件:** `ubains-meeting-provider/.../welink/service/impl/WelinkMeetingServiceImpl.java:1628`
**现象:** ERROR 日志(11MB)全是同一个异常:
```
org.apache.ibatis.exceptions.TooManyResultsException:
Expected one result (or null) to be returned by selectOne(), but found: 2
```
**调用链:**
```
welinkSyncRoomsAndMeeingsQuartz.syncMeetings()
→ WelinkMeetingServiceImpl.syncWelinkMeeting()
→ WelinkMeetingServiceImpl.getThirdMessageByRoomId()
→ ConferenceServiceImpl.getOne() // 返回了2条记录
```
**影响:** 每分钟 WeLink 同步定时任务触发时都会抛异常,产生大量错误日志和堆栈,消耗 CPU、磁盘 I/O 和数据库连接。
---
#### B4. Druid 数据库连接池配置偏小(中风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/application-ubains.properties`
| 配置项 | 当前值 | 建议值 | 说明 |
|--------|--------|--------|------|
| `maxActive` | **20** | 50 | 59个定时任务 + Tomcat 200线程共享20个连接 |
| `maxWait` | 60000 | 30000 | 获取连接等60秒太长,应用会假死 |
| `minIdle` | 5 | 10 | 空闲连接太少 |
| `removeAbandoned` | 未配置 | true | 未开启连接泄漏回收 |
| `removeAbandonedTimeout` | 未配置 | 300 | 泄漏连接5分钟后回收 |
**影响:** 定时任务大量查询数据库时,HTTP 请求获取连接需等待最多 60 秒,表现为"进程存在但不响应"。
---
#### B5. Tomcat 线程池未显式配置(低风险)
**涉及文件:** `application-ubains.properties`
当前只配置了 `server.tomcat.uri-encoding=UTF-8`,未配置以下关键参数:
| 配置项 | 默认值 | 建议值 | 说明 |
|--------|--------|--------|------|
| `server.tomcat.threads.max` | 200 | 200(保持) | 最大工作线程 |
| `server.tomcat.max-connections` | 8192 | 2000 | 最大连接数 |
| `server.connection-timeout` | 20s | 20s(保持) | 连接超时 |
| `server.tomcat.accept-count` | 100 | 200 | 等待队列长度 |
---
## 三、优化方案
### P0 — 必须立即修复
#### 优化1:统一 JVM 启动参数
**操作:** 修改服务器 `run.sh`,与实际运行参数一致,并添加 OOM 诊断参数
**修改前:**
```sh
nohup java -Xms1024m -Xmx2048m -jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**修改后:**
```sh
nohup java -Xms2048m -Xmx4096m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=$SERVICE_DIR/logs/ \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:$SERVICE_DIR/logs/gc.log \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=10 \
-XX:GCLogFileSize=50M \
-jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**验证方式:** 重启后通过 `ps aux | grep java` 确认参数生效
**实现状态:** [ ] 待实现
---
#### 优化2:修复定时任务线程池大小
**操作:** 修改 `ScheduleThreadPool.java`,将线程池大小从 10 增加到 50
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/quartz/ScheduleThreadPool.java`
**修改前:**
```java
int defaultPoolSize = 10;
int corePoolSize = 0;
if (methods != null && methods.length > 0) {
for (Method method : methods) {
Scheduled annotation = method.getAnnotation(Scheduled.class);
if (annotation != null) {
corePoolSize++;
}
}
if (defaultPoolSize > corePoolSize)
corePoolSize = defaultPoolSize;
}
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
```
**修改后:**
```java
int defaultPoolSize = 50;
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(defaultPoolSize));
```
**理由:** 原有代码扫描 `BatchProperties.Job.class` 获取线程数的逻辑本身就是错误的,直接使用固定值 50 即可(项目有 59 个定时任务文件)。
**实现状态:** [ ] 待实现
---
#### 优化3:移除 `RedisLockAspect` 中的无效 sleep
**操作:** 删除 `Thread.sleep(PROTECT_TIME)` 调用
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/quartz/RedisLockAspect.java`
**修改前(两个分支都有):**
```java
if (loadBalanceSwitch) {
Boolean flag = this.getLock(proceeding, 0, System.currentTimeMillis());
if (flag) {
try {
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // 删除此行
} catch (Throwable throwable) { ... }
finally { this.delLock(proceeding); }
}
} else {
try {
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // 删除此行
} catch (Throwable e) { ... }
}
```
**修改后:** 两处 `Thread.sleep(PROTECT_TIME)` 均删除
**理由:** 这个 sleep 没有实际业务意义,只是增加了每次定时任务 4 秒的无效等待,在 59 个任务的场景下累计浪费 236 秒线程时间。
**实现状态:** [ ] 待实现
---
### P1 — 尽快修复
#### 优化4:增大数据库连接池
**操作:** 修改 `application-ubains.properties` 中的 Druid 配置
**涉及文件:** `ubains-meeting-inner-api/src/main/resources/config/application-ubains.properties`
| 配置项 | 修改前 | 修改后 |
|--------|--------|--------|
| `spring.datasource.maxActive` | 20 | **50** |
| `spring.datasource.maxWait` | 60000 | **30000** |
| `spring.datasource.minIdle` | 5 | **10** |
| `spring.datasource.initialSize` | 5 | **10** |
**新增配置:**
```properties
# 连接泄漏回收
spring.datasource.removeAbandoned=true
spring.datasource.removeAbandonedTimeout=300
spring.datasource.logAbandoned=true
```
**实现状态:** [ ] 待实现
---
#### 优化5:修复 WeLink 同步 TooManyResultsException
**操作:** 修复 `WelinkMeetingServiceImpl.getThirdMessageByRoomId()` 中的查询条件
**涉及文件:** `ubains-meeting-provider/src/main/java/com/ubains/meeting/welink/service/impl/WelinkMeetingServiceImpl.java:1628`
**问题:** `getOne()` 查询返回了 2 条记录,需要增加查询条件的唯一性或改用 `list()` + 取第一条
**修复方向:**
- 方案A:排查数据库中 `rms_meeting_message` 表对应字段是否存在重复数据,清理重复数据
- 方案B:在 `getOne()` 的 QueryWrapper 中增加更多条件确保唯一性
- 方案C:改用 `getOne(wrapper, false)` (MyBatis-Plus 的第二个参数 `false` 表示有多条时取第一条不报错)
**实现状态:** [ ] 待实现
---
#### 优化6:`System.exit(0)` 改为抛出异常
**操作:**`MybatisPlusConfig.java` 中的 `System.exit(0)` 改为抛出 `RuntimeException`
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/MybatisPlusConfig.java:216-219`
**修改前:**
```java
if (!(localSHA3.equals(startCode))) {
logger.info("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
System.exit(0);
}
```
**修改后:**
```java
if (!(localSHA3.equals(startCode))) {
logger.error("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
throw new RuntimeException("授权校验失败:CPU序列号或MAC地址不匹配");
}
```
**理由:** 抛出异常会让 Spring Boot 启动失败并打印完整的错误堆栈,便于排查问题,同时 Docker 的 `--restart=always` 策略会自动重启容器。而 `System.exit(0)` 直接退出 JVM,退出码为 0(表示正常退出),Docker 可能不会重启容器。
**实现状态:** [ ] 待实现
---
### P2 — 建议修复
#### 优化7:`run.sh` 使用优雅停止
**操作:** 修改服务器 `run.sh` 的 stop 逻辑
**修改前:**
```sh
stop)
kill -9 `cat $SERVICE_DIR/$PID`
```
**修改后:**
```sh
stop)
PID_VAL=`cat $SERVICE_DIR/$PID 2>/dev/null`
if [ -n "$PID_VAL" ]; then
kill -15 $PID_VAL
echo "=== waiting for graceful shutdown..."
# 等待最多30秒
for i in $(seq 1 30); do
if ! kill -0 $PID_VAL 2>/dev/null; then
echo "=== $SERVICE_NAME stopped gracefully"
break
fi
sleep 1
done
# 如果还没停止,强杀
if kill -0 $PID_VAL 2>/dev/null; then
echo "=== force killing $SERVICE_NAME"
kill -9 $PID_VAL
fi
fi
rm -rf $SERVICE_DIR/$PID
```
**实现状态:** [ ] 待实现
---
#### 优化8:添加进程健康检查脚本
**操作:** 在容器内添加健康检查脚本,定时检测 HTTP 端口是否响应
**新增文件:** 服务器 `/var/www/java/api-java-meeting2.0/healthcheck.sh`
```sh
#!/bin/bash
# 健康检查脚本,检测 HTTP 端口是否响应
HEALTH_URL="http://127.0.0.1:8999/actuator/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 $HEALTH_URL 2>/dev/null)
if [ "$RESPONSE" != "200" ]; then
echo "[$(date)] Health check failed (HTTP $RESPONSE), restarting..." >> /var/www/java/api-java-meeting2.0/logs/healthcheck.log
cd /var/www/java/api-java-meeting2.0
./run.sh
else
echo "[$(date)] Health check passed" >> /var/www/java/api-java-meeting2.0/logs/healthcheck.log
fi
```
配合 crontab(在 `start.sh` 末尾添加):
```sh
# 每5分钟检查一次
* * * * * /var/www/java/api-java-meeting2.0/healthcheck.sh
```
**实现状态:** [ ] 待实现
---
## 四、优化执行清单
| 序号 | 优先级 | 优化项 | 修改方式 | 涉及文件 | 实现状态 |
|------|--------|--------|---------|---------|----------|
| 1 | P0 | 统一 JVM 启动参数 | 手动修改服务器文件 | 服务器 `run.sh` | [ ] |
| 2 | P0 | 修复定时任务线程池大小 | 修改代码 | `ScheduleThreadPool.java` | [ ] |
| 3 | P0 | 移除无效 Thread.sleep | 修改代码 | `RedisLockAspect.java` | [ ] |
| 4 | P1 | 增大数据库连接池 | 修改配置 | `application-ubains.properties` | [ ] |
| 5 | P1 | 修复 WeLink 同步异常 | 修改代码 | `WelinkMeetingServiceImpl.java` | [ ] |
| 6 | P1 | System.exit 改为异常 | 修改代码 | `MybatisPlusConfig.java` | [ ] |
| 7 | P2 | 优雅停止 | 手动修改服务器文件 | 服务器 `run.sh` | [ ] |
| 8 | P2 | 添加健康检查 | 新增脚本 | 服务器新增 `healthcheck.sh` | [ ] |
---
## 五、验证方案
修改部署后,通过以下方式验证:
```bash
# 1. 确认 JVM 参数
docker exec ujava2 ps aux | grep java
# 2. 观察线程数变化(应趋于稳定)
docker exec ujava2 ls /proc/$(docker exec ujava2 pgrep -f ubains-meeting-inner)/task | wc -l
# 3. 观察内存使用
docker stats ujava2 --no-stream
# 4. 确认 ERROR 日志不再增长
ls -lh /var/www/java/api-java-meeting2.0/logs/ubains-ERROR.log
# 5. 确认应用响应正常
curl -s -o /dev/null -w "%{http_code}" http://192.168.5.50:8999/actuator/health
# 6. 观察 GC 日志(优化1添加后)
tail -50 /var/www/java/api-java-meeting2.0/logs/gc.log
```
---
## 六、代码执行记录
### 代码执行1:优化2 - 修复定时任务线程池大小
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行2:优化3 - 移除无效 Thread.sleep
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行3:优化4 - 增大数据库连接池
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行4:优化5 - 修复 WeLink 同步异常
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行5:优化6 - System.exit 改为异常
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
---
## 七、优化功能回填
> 本章节用于记录优化过程中发现的新问题和改进措施
| 序号 | 发现时间 | 问题描述 | 处理措施 | 状态 |
|------|---------|---------|---------|------|
| 1 | | | | [ ] |
---
## 📝 附录
### 代码规范
- 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 严格按照问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 严格按照方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 严格按照文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 严格按照测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
### 问题记录与规避
- 执行时,按照 `Docs/PRD/日志监测/_PRD_方法总结_记录文档.md`,累计记录所积累的经验,规避已经出现过的问题
## 📋 背景
- 预定系统,支持预约会议、签到、联动无纸化等功能
**服务器IP**:192.168.5.45 root 密码 Ubains@123
**容器内主服务部署路径**:/var/www/java/api/api-java-meeting2.0
**宿主机主服务部署路径**, /data/services/api/java-meeting/java-meeting2.0
**容器内对外服务部署路径**:/var/www/java/api/api-java-meeting-extapi
**宿主机对外服务部署路径**, /data/services/api/java-meeting/java-meeting-extapi
**容器内鉴权服务部署路径**:/var/www/java/api/auth/auth-sso-auth、/var/www/java/api/auth/auth-sso-gatway、/var/www/java/api/auth/auth-sso-system
**宿主机对外服务部署路径**, /data/services/api/auth/auth-sso-auth、/data/services/api/auth/auth-sso-gatway、/data/services/api/auth/auth-sso-system
**部署容器** docker环境:ujava2
## 🎯 任务
### 问题1: 监查查询项目运行为什么有时出现进程消失的问题,有时间进程存在但不运行
- 查找代码的优化项,找出优化或配置问题
- 登录服务器,监测相关的运行情况结合代码进行优化
### 分析结果:
- `Docs/PRD/日志监测/分析报告/新统一平台/负载二`
### 代码规范
- 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 严格按照问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 严格按照方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 严格按照文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 严格按照测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
### 问题记录与规避
- 执行时,按照Docs/PRD/日志监测/_PRD_方法总结_记录文档.md,累计的记录所积累的经验,规避已经出现过的问题
- 执行时,按照Docs/PRD/日志监测/_PRD_方法总结_记录文档.md,累计的记录所积累的经验,规避已经出现过的问题
\ No newline at end of file
# 会议系统进程消失/进程存在但不运行 — 问题分析与优化方案
## 📋 背景
- 预定系统,支持预约会议、签到、联动无纸化等功能
**服务器IP**:192.168.5.45 root 密码 Ubains@123
**部署容器**:docker环境:ujava2
### 服务列表
| 服务名称 | 容器内部署路径 | 宿主机部署路径 | 日志文件 |
|---------|---------------|---------------|---------|
| **主服务** | `/var/www/java/api/java-meeting/java-meeting2.0` | `/data/services/api/java-meeting/java-meeting2.0` | `logs/ubains-INFO-AND-ERROR.log` |
| **对外服务** | `/var/www/java/api/java-meeting/java-meeting-extapi` | `/data/services/api/java-meeting/java-meeting-extapi` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-认证** | `/var/www/java/api/auth/auth-sso-auth` | `/data/services/api/auth/auth-sso-auth` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-网关** | `/var/www/java/api/auth/auth-sso-gatway` | `/data/services/api/auth/auth-sso-gatway` | `logs/ubains-INFO-AND-ERROR.log` |
| **鉴权服务-系统** | `/var/www/java/api/auth/auth-sso-system` | `/data/services/api/auth/auth-sso-system` | `logs/ubains-INFO-AND-ERROR.log` |
## 🎯 任务
### 问题:监查查询项目运行为什么有时出现进程消失的问题,有时间进程存在但不运行
- 查找代码的优化项,找出优化或配置问题
- 登录服务器,监测相关的运行情况结合代码进行优化
---
## 一、服务器运行现状(2026-04-22 11:05 采集)
| 指标 | 值 | 状态 |
|------|-----|------|
| 服务器IP | 192.168.5.50 | - |
| Docker容器 | ujava2 | - |
| 容器内存限制 | **无限制**(0) | 宿主机 7.25GiB |
| 当前内存使用 | **2.43GiB**(33.5%) | 正常 |
| Docker 重启策略 | `always`,重启次数 **0** | 容器未重启过 |
| JVM 启动参数 | `-Xms2048m -Xmx4096m` | 与 run.sh 不一致 |
| Java 线程数 | **149** | 偏高 |
| Socket FD 数 | **21** | 正常 |
| 进程运行时长 | **23小时20分** | 当前存活 |
| ERROR 日志 | **11MB**,全是 `TooManyResultsException` | 需修复 |
| 部署路径 | `/var/www/java/api-java-meeting2.0` | - |
---
## 二、问题分析
### 问题A:进程消失(进程直接退出)
#### A1. JVM 参数不一致 — 部署脚本未更新(高风险)
**现状对比:**
| 来源 | -Xms | -Xmx |
|------|------|------|
| `run.sh` 中定义 | 1024m | **2048m** |
| 实际运行进程 | 2048m | **4096m** |
**问题原因:** 有人手动修改过启动参数或有另一套启动流程,但 `run.sh` 未同步更新。
**影响:** 通过 `start.sh``run.sh` 重启时,JVM 堆内存会从当前的 4096m 降回 **2048m**,在 149 个线程 + 59 个定时任务的高负载下,极易触发 OOM 导致进程消失。
**涉及文件:**
- 服务器 `/var/www/java/api-java-meeting2.0/run.sh`(不在代码仓库中)
- 服务器 `/var/www/java/start.sh`(容器入口)
**`run.sh` 当前内容:**
```sh
start)
nohup java -Xms1024m -Xmx2048m -jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**`start.sh` 当前内容:**
```sh
/usr/local/nginx/sbin/nginx
sleep 2
cd /var/www/java/api-java-meeting2.0
./run.sh # 不传参数,走 *) 分支 = stop + start,使用 run.sh 里的 -Xmx2048m
sleep 60
cd /var/www/java/api-dubbo-welink
./run.sh # 启动第二个 Java 进程
```
---
#### A2. 两个 Java 进程内存总和超限(高风险)
`start.sh` 启动了两个 Java 进程:
| 进程 | -Xms | -Xmx | 实际 RSS |
|------|------|------|----------|
| meeting 2.0 | 2048m | **4096m** | ~1.6GB |
| api-dubbo-welink | 1024m | **2048m** | ~800MB |
| **合计** | 3072m | **6144m** | ~2.5GB |
宿主机总内存 7.25GiB,两个 Java 进程理论最大可占 **6GB**,加上操作系统和其他进程,极易触发 Linux OOM Killer。
**影响:** 当 meeting 2.0 进行大量定时任务处理时,堆内存突增,超过可用内存,Linux OOM Killer 直接杀掉 Java 进程。
---
#### A3. `System.exit(0)` 在授权校验失败时直接退出(中风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/MybatisPlusConfig.java:216-218`
```java
if (!(localSHA3.equals(startCode))) {
logger.info("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
System.exit(0);
}
```
**问题原因:** Docker 容器重启后,虚拟化环境下 MAC 地址或 CPU 序号可能变化,导致授权校验失败。
**其他 `System.exit(0)` 调用点:**
| 文件 | 行号 | 触发条件 |
|------|------|---------|
| `MybatisPlusConfig.java` | 218 | CPU/MAC 与授权文件不匹配 |
| `AdjustmentDb.java` | 355 | 数据库结构调整失败 |
| `FaceEngineManager.java` | 52, 71 | 人脸引擎激活失败 |
---
#### A4. `run.sh` 使用 `kill -9` 强杀进程(低风险)
**涉及文件:** 服务器 `run.sh`
```sh
stop)
kill -9 `cat $SERVICE_DIR/$PID`
```
`kill -9` 不执行 Spring Boot 优雅关闭,可能导致数据库连接未释放、Redis 连接残留、临时文件未清理。
---
### 问题B:进程存在但不运行(假死)
#### B1. 定时任务线程池严重不足(高风险 — 最可能的元凶)
**涉及文件:** `ubains-meeting-inner-api/.../config/quartz/ScheduleThreadPool.java`
```java
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
Method[] methods = BatchProperties.Job.class.getMethods(); // BUG:扫描的是错误的类
int defaultPoolSize = 10;
int corePoolSize = 0;
// ... 遍历 BatchProperties.Job 的方法,不会找到任何 @Scheduled 注解
// 最终 corePoolSize = 0 < 10,被 defaultPoolSize=10 兜底
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
}
```
**问题分析:**
- 代码扫描的是 `BatchProperties.Job.class` 的方法,而不是项目中实际的 `@Scheduled` 方法
- 结果线程池大小固定为 **10 个线程**
- 项目中实际有 **59 个 `@Scheduled` 定时任务文件**(inner-api 模块)
- 当前 Java 进程已有 **149 个线程**,定时任务调度线程远不够用
**影响:** 多个定时任务同时触发时排队等待,如果某个任务执行时间很长(如 `SendMessageQuartz` 500+ 行代码),会阻塞其他所有任务的调度,最终导致应用无法响应 HTTP 请求。
---
#### B2. `RedisLockAspect` 每个定时任务执行后 sleep 4秒(高风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/quartz/RedisLockAspect.java:60-61, 72-73`
```java
// 无论是否启用负载均衡,都会 sleep
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // PROTECT_TIME = 2 << 11 = 4096ms
```
**问题分析:**
- 每个带 `@RedisLock` 注解的定时任务执行完后都会**强制 sleep 4秒**
- 59 个定时任务中大量使用了 `@RedisLock` 注解
- 累计无效等待时间可达 **236 秒**(59 × 4秒)
- 在仅 10 个调度线程的条件下,这些 sleep 占满了宝贵的线程资源
**影响:** 定时任务执行效率极低,大量线程被 sleep 占据,无法及时处理新的定时触发和 HTTP 请求。
---
#### B3. WeLink 同步持续抛出异常(中风险)
**涉及文件:** `ubains-meeting-provider/.../welink/service/impl/WelinkMeetingServiceImpl.java:1628`
**现象:** ERROR 日志(11MB)全是同一个异常:
```
org.apache.ibatis.exceptions.TooManyResultsException:
Expected one result (or null) to be returned by selectOne(), but found: 2
```
**调用链:**
```
welinkSyncRoomsAndMeeingsQuartz.syncMeetings()
→ WelinkMeetingServiceImpl.syncWelinkMeeting()
→ WelinkMeetingServiceImpl.getThirdMessageByRoomId()
→ ConferenceServiceImpl.getOne() // 返回了2条记录
```
**影响:** 每分钟 WeLink 同步定时任务触发时都会抛异常,产生大量错误日志和堆栈,消耗 CPU、磁盘 I/O 和数据库连接。
---
#### B4. Druid 数据库连接池配置偏小(中风险)
**涉及文件:** `ubains-meeting-inner-api/.../config/application-ubains.properties`
| 配置项 | 当前值 | 建议值 | 说明 |
|--------|--------|--------|------|
| `maxActive` | **20** | 50 | 59个定时任务 + Tomcat 200线程共享20个连接 |
| `maxWait` | 60000 | 30000 | 获取连接等60秒太长,应用会假死 |
| `minIdle` | 5 | 10 | 空闲连接太少 |
| `removeAbandoned` | 未配置 | true | 未开启连接泄漏回收 |
| `removeAbandonedTimeout` | 未配置 | 300 | 泄漏连接5分钟后回收 |
**影响:** 定时任务大量查询数据库时,HTTP 请求获取连接需等待最多 60 秒,表现为"进程存在但不响应"。
---
#### B5. Tomcat 线程池未显式配置(低风险)
**涉及文件:** `application-ubains.properties`
当前只配置了 `server.tomcat.uri-encoding=UTF-8`,未配置以下关键参数:
| 配置项 | 默认值 | 建议值 | 说明 |
|--------|--------|--------|------|
| `server.tomcat.threads.max` | 200 | 200(保持) | 最大工作线程 |
| `server.tomcat.max-connections` | 8192 | 2000 | 最大连接数 |
| `server.connection-timeout` | 20s | 20s(保持) | 连接超时 |
| `server.tomcat.accept-count` | 100 | 200 | 等待队列长度 |
---
## 三、优化方案
### P0 — 必须立即修复
#### 优化1:统一 JVM 启动参数
**操作:** 修改服务器 `run.sh`,与实际运行参数一致,并添加 OOM 诊断参数
**修改前:**
```sh
nohup java -Xms1024m -Xmx2048m -jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**修改后:**
```sh
nohup java -Xms2048m -Xmx4096m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=$SERVICE_DIR/logs/ \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:$SERVICE_DIR/logs/gc.log \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=10 \
-XX:GCLogFileSize=50M \
-jar -DAPP_CONFIG=$home $JAR_NAME > $SERVICE_DIR/logs/ubains-INFO-AND-ERROR.log 2>&1 &
```
**验证方式:** 重启后通过 `ps aux | grep java` 确认参数生效
**实现状态:** [ ] 待实现
---
#### 优化2:修复定时任务线程池大小
**操作:** 修改 `ScheduleThreadPool.java`,将线程池大小从 10 增加到 50
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/quartz/ScheduleThreadPool.java`
**修改前:**
```java
int defaultPoolSize = 10;
int corePoolSize = 0;
if (methods != null && methods.length > 0) {
for (Method method : methods) {
Scheduled annotation = method.getAnnotation(Scheduled.class);
if (annotation != null) {
corePoolSize++;
}
}
if (defaultPoolSize > corePoolSize)
corePoolSize = defaultPoolSize;
}
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
```
**修改后:**
```java
int defaultPoolSize = 50;
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(defaultPoolSize));
```
**理由:** 原有代码扫描 `BatchProperties.Job.class` 获取线程数的逻辑本身就是错误的,直接使用固定值 50 即可(项目有 59 个定时任务文件)。
**实现状态:** [ ] 待实现
---
#### 优化3:移除 `RedisLockAspect` 中的无效 sleep
**操作:** 删除 `Thread.sleep(PROTECT_TIME)` 调用
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/quartz/RedisLockAspect.java`
**修改前(两个分支都有):**
```java
if (loadBalanceSwitch) {
Boolean flag = this.getLock(proceeding, 0, System.currentTimeMillis());
if (flag) {
try {
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // 删除此行
} catch (Throwable throwable) { ... }
finally { this.delLock(proceeding); }
}
} else {
try {
proceeding.proceed();
Thread.sleep(PROTECT_TIME); // 删除此行
} catch (Throwable e) { ... }
}
```
**修改后:** 两处 `Thread.sleep(PROTECT_TIME)` 均删除
**理由:** 这个 sleep 没有实际业务意义,只是增加了每次定时任务 4 秒的无效等待,在 59 个任务的场景下累计浪费 236 秒线程时间。
**实现状态:** [ ] 待实现
---
### P1 — 尽快修复
#### 优化4:增大数据库连接池
**操作:** 修改 `application-ubains.properties` 中的 Druid 配置
**涉及文件:** `ubains-meeting-inner-api/src/main/resources/config/application-ubains.properties`
| 配置项 | 修改前 | 修改后 |
|--------|--------|--------|
| `spring.datasource.maxActive` | 20 | **50** |
| `spring.datasource.maxWait` | 60000 | **30000** |
| `spring.datasource.minIdle` | 5 | **10** |
| `spring.datasource.initialSize` | 5 | **10** |
**新增配置:**
```properties
# 连接泄漏回收
spring.datasource.removeAbandoned=true
spring.datasource.removeAbandonedTimeout=300
spring.datasource.logAbandoned=true
```
**实现状态:** [ ] 待实现
---
#### 优化5:修复 WeLink 同步 TooManyResultsException
**操作:** 修复 `WelinkMeetingServiceImpl.getThirdMessageByRoomId()` 中的查询条件
**涉及文件:** `ubains-meeting-provider/src/main/java/com/ubains/meeting/welink/service/impl/WelinkMeetingServiceImpl.java:1628`
**问题:** `getOne()` 查询返回了 2 条记录,需要增加查询条件的唯一性或改用 `list()` + 取第一条
**修复方向:**
- 方案A:排查数据库中 `rms_meeting_message` 表对应字段是否存在重复数据,清理重复数据
- 方案B:在 `getOne()` 的 QueryWrapper 中增加更多条件确保唯一性
- 方案C:改用 `getOne(wrapper, false)` (MyBatis-Plus 的第二个参数 `false` 表示有多条时取第一条不报错)
**实现状态:** [ ] 待实现
---
#### 优化6:`System.exit(0)` 改为抛出异常
**操作:**`MybatisPlusConfig.java` 中的 `System.exit(0)` 改为抛出 `RuntimeException`
**涉及文件:** `ubains-meeting-inner-api/src/main/java/com/ubains/config/MybatisPlusConfig.java:216-219`
**修改前:**
```java
if (!(localSHA3.equals(startCode))) {
logger.info("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
System.exit(0);
}
```
**修改后:**
```java
if (!(localSHA3.equals(startCode))) {
logger.error("cpu序列号或mac地址不匹配,系统启动失败,请联系部署运维人员沟通");
throw new RuntimeException("授权校验失败:CPU序列号或MAC地址不匹配");
}
```
**理由:** 抛出异常会让 Spring Boot 启动失败并打印完整的错误堆栈,便于排查问题,同时 Docker 的 `--restart=always` 策略会自动重启容器。而 `System.exit(0)` 直接退出 JVM,退出码为 0(表示正常退出),Docker 可能不会重启容器。
**实现状态:** [ ] 待实现
---
### P2 — 建议修复
#### 优化7:`run.sh` 使用优雅停止
**操作:** 修改服务器 `run.sh` 的 stop 逻辑
**修改前:**
```sh
stop)
kill -9 `cat $SERVICE_DIR/$PID`
```
**修改后:**
```sh
stop)
PID_VAL=`cat $SERVICE_DIR/$PID 2>/dev/null`
if [ -n "$PID_VAL" ]; then
kill -15 $PID_VAL
echo "=== waiting for graceful shutdown..."
# 等待最多30秒
for i in $(seq 1 30); do
if ! kill -0 $PID_VAL 2>/dev/null; then
echo "=== $SERVICE_NAME stopped gracefully"
break
fi
sleep 1
done
# 如果还没停止,强杀
if kill -0 $PID_VAL 2>/dev/null; then
echo "=== force killing $SERVICE_NAME"
kill -9 $PID_VAL
fi
fi
rm -rf $SERVICE_DIR/$PID
```
**实现状态:** [ ] 待实现
---
#### 优化8:添加进程健康检查脚本
**操作:** 在容器内添加健康检查脚本,定时检测 HTTP 端口是否响应
**新增文件:** 服务器 `/var/www/java/api-java-meeting2.0/healthcheck.sh`
```sh
#!/bin/bash
# 健康检查脚本,检测 HTTP 端口是否响应
HEALTH_URL="http://127.0.0.1:8999/actuator/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 $HEALTH_URL 2>/dev/null)
if [ "$RESPONSE" != "200" ]; then
echo "[$(date)] Health check failed (HTTP $RESPONSE), restarting..." >> /var/www/java/api-java-meeting2.0/logs/healthcheck.log
cd /var/www/java/api-java-meeting2.0
./run.sh
else
echo "[$(date)] Health check passed" >> /var/www/java/api-java-meeting2.0/logs/healthcheck.log
fi
```
配合 crontab(在 `start.sh` 末尾添加):
```sh
# 每5分钟检查一次
* * * * * /var/www/java/api-java-meeting2.0/healthcheck.sh
```
**实现状态:** [ ] 待实现
---
## 四、优化执行清单
| 序号 | 优先级 | 优化项 | 修改方式 | 涉及文件 | 实现状态 |
|------|--------|--------|---------|---------|----------|
| 1 | P0 | 统一 JVM 启动参数 | 手动修改服务器文件 | 服务器 `run.sh` | [ ] |
| 2 | P0 | 修复定时任务线程池大小 | 修改代码 | `ScheduleThreadPool.java` | [ ] |
| 3 | P0 | 移除无效 Thread.sleep | 修改代码 | `RedisLockAspect.java` | [ ] |
| 4 | P1 | 增大数据库连接池 | 修改配置 | `application-ubains.properties` | [ ] |
| 5 | P1 | 修复 WeLink 同步异常 | 修改代码 | `WelinkMeetingServiceImpl.java` | [ ] |
| 6 | P1 | System.exit 改为异常 | 修改代码 | `MybatisPlusConfig.java` | [ ] |
| 7 | P2 | 优雅停止 | 手动修改服务器文件 | 服务器 `run.sh` | [ ] |
| 8 | P2 | 添加健康检查 | 新增脚本 | 服务器新增 `healthcheck.sh` | [ ] |
---
## 五、验证方案
修改部署后,通过以下方式验证:
```bash
# 1. 确认 JVM 参数
docker exec ujava2 ps aux | grep java
# 2. 观察线程数变化(应趋于稳定)
docker exec ujava2 ls /proc/$(docker exec ujava2 pgrep -f ubains-meeting-inner)/task | wc -l
# 3. 观察内存使用
docker stats ujava2 --no-stream
# 4. 确认 ERROR 日志不再增长
ls -lh /var/www/java/api-java-meeting2.0/logs/ubains-ERROR.log
# 5. 确认应用响应正常
curl -s -o /dev/null -w "%{http_code}" http://192.168.5.50:8999/actuator/health
# 6. 观察 GC 日志(优化1添加后)
tail -50 /var/www/java/api-java-meeting2.0/logs/gc.log
```
---
## 六、代码执行记录
### 代码执行1:优化2 - 修复定时任务线程池大小
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行2:优化3 - 移除无效 Thread.sleep
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行3:优化4 - 增大数据库连接池
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行4:优化5 - 修复 WeLink 同步异常
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
### 代码执行5:优化6 - System.exit 改为异常
**执行时间:** 待定
**执行结果:** [ ] 成功 / [ ] 失败
**备注:**
---
## 七、优化功能回填
> 本章节用于记录优化过程中发现的新问题和改进措施
| 序号 | 发现时间 | 问题描述 | 处理措施 | 状态 |
|------|---------|---------|---------|------|
| 1 | | | | [ ] |
---
## 📝 附录
### 代码规范
- 严格按照代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 严格按照问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 严格按照方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 严格按照文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 严格按照测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
### 问题记录与规避
- 执行时,按照 `Docs/PRD/日志监测/_PRD_方法总结_记录文档.md`,累计记录所积累的经验,规避已经出现过的问题
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论