QAUP_Management/doc/work/数据采集间隔优化_20250117.md

166 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据采集间隔优化与WebSocket节流机制实现
## 问题描述
用户发现前端收到的运动物体位置数据不连续经常收到位置相同、速度为0的数据。
## 问题分析
1. **时序同步问题**
- Mock服务器每1000ms更新一次位置
- 数据采集服务也是每1000ms采集一次
- 两者同步执行时可能出现采集时mock服务器还未更新位置的情况
- 导致采集到相同位置→计算距离为0→速度为0
2. **数据流异常**
- 前端收到位置相同的数据
- 速度计算结果为0
- 影响用户体验和数据准确性
## 解决方案
按照用户建议,实现**高频采集+节流推送**机制:
### 1. 提高数据采集频率
- 采集间隔从1000ms→500ms→250ms逐步优化最终每秒4次
- 大幅降低与mock服务器时序冲突的概率
- 确保能够及时获取最新位置数据,最大化避免停顿现象
### 2. 实现WebSocket推送节流
- 虽然采集频率提高但WebSocket推送仍保持1000ms间隔
- 避免前端接收过多数据,保持合理的推送频率
- 通过节流机制平衡数据实时性和性能
## 技术实现
### 1. 配置文件优化
在全局配置文件`qaup-admin/src/main/resources/application.yml`中修改:
```yaml
data:
collector:
interval: 500 # 数据采集间隔500ms从1000ms优化
websocket:
push-interval: 1000 # WebSocket推送间隔1000ms
```
### 2. WebSocket节流机制
在`DataCollectorService`中添加:
- `lastPushTimes`: 跟踪每个对象的上次推送时间
- `shouldPushWebSocketMessage()`: 检查是否应该推送消息
- 对每个数据处理循环添加节流检查
### 3. 服务整合优化
解决了之前的SpeedCalculationService Bean冲突问题
- 删除重复的common包中的服务
- 增强现有的dataprocessing包中的服务
- 添加实时速度计算功能
## 代码变更
### 1. 数据采集配置
```yaml
# 数据采集间隔500ms每秒2次
interval: 500
# WebSocket推送节流1000ms每秒1次
websocket:
push-interval: 1000
```
### 2. 节流机制实现
```java
/**
* WebSocket推送节流机制
*/
private final Map<String, Long> lastPushTimes = new ConcurrentHashMap<>();
private boolean shouldPushWebSocketMessage(String objectId, long currentTime) {
Long lastPushTime = lastPushTimes.get(objectId);
if (lastPushTime == null || (currentTime - lastPushTime) >= websocketPushInterval) {
lastPushTimes.put(objectId, currentTime);
return true;
}
return false;
}
```
### 3. 数据处理优化
为三种数据类型(航空器、机场车辆、无人车)都添加了节流检查:
```java
// 节流检查只有达到推送间隔时才发布WebSocket事件
if (shouldPushWebSocketMessage(objectId, currentTime)) {
eventPublisher.publishEvent(new PositionUpdateEvent(payload));
log.debug("处理数据并发布事件: {} (速度: {})", objectId, finalSpeed);
} else {
log.trace("数据采集但未推送(节流): {} (速度: {})", objectId, finalSpeed);
}
```
## 预期效果
### 1. 数据连续性改善
- 采集频率提高到500ms确保及时获取最新位置
- 避免位置相同的问题
- 速度计算更加准确
### 2. 性能平衡
- 推送频率保持1000ms避免前端过载
- 节流机制减少不必要的WebSocket通信
- 日志分级trace级别记录节流信息
### 3. 系统稳定性
- Bean冲突问题已解决
- 编译成功,无语法错误
- 保持系统架构的整洁性
## 测试验证
1. ✅ 编译成功,无语法错误
2. ✅ Bean冲突问题解决
3. ✅ 配置文件正确加载
4. ✅ 节流机制正常工作
## 关键Bug修复 - 速度计算逻辑根本性错误
### 问题发现
用户反馈两个关键问题:
1. **速度计算错误**显然是用距离除了250ms时间间隔甚至达到了54米每秒
2. **大部分速度都是0**250ms内位置没变化距离为0速度为0
### 根因分析
**核心误区**:混淆了数据采集频率和速度计算频率
- **错误逻辑**250ms采集 → 250ms计算速度 → 节流推送
- **正确逻辑**250ms采集 → 缓存位置 → 1000ms计算速度 → 1000ms推送
### 用户洞察
> "我们提高采样频率,为的是获取到数据,而不是为了提高计算频率。速度计算应该是以输出频率来计算。"
### 修复方案
```java
// 修复前:基于采集频率计算,导致速度异常
if (timeDelta < 0.05) { // 50ms与250ms采集间隔比较
return lastPosition.lastCalculatedSpeed;
}
// 修复后:基于输出频率计算,确保速度准确
@Value("${data.collector.websocket.push-interval:1000}")
private long websocketPushInterval;
double pushIntervalSeconds = websocketPushInterval / 1000.0;
if (timeDelta < pushIntervalSeconds) { // 从配置文件读取,不硬编码
return lastPosition.lastCalculatedSpeed;
}
```
### 修复效果
-**采集与计算分离**250ms采集缓存数据基于配置的间隔计算速度
-**速度计算准确**基于WebSocket推送间隔的充分位置变化计算
-**避免异常值**消除54m/s等因短时间间隔导致的异常速度
-**减少0速度**:基于更长时间间隔,有足够位置变化用于计算
-**配置化设计**:从配置文件读取输出频率,避免硬编码
## 后续优化建议
1. 监控实际运行效果,根据需要调整采集间隔
2. 考虑添加动态配置功能,允许运行时调整间隔
3. 增加性能监控,跟踪节流效果
---
**实现时间**: 2025-01-17
**版本**: 0.3.1
**状态**: 已完成