QAUP_Management/doc/work/数据采集间隔优化_20250117.md
Tian jianyong 5e1e9f4507 统一了前后端到一个项目,实现了无人车的位置和超速检测,并发送到前端。
管理端在 Ruoyi 框架的基础上,对菜单进行了修改,并添加了司机信息、车辆信息和车辆类型管理。
2025-07-08 20:04:14 +08:00

5.5 KiB
Raw Permalink Blame History

数据采集间隔优化与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中修改:

data:
  collector:
    interval: 500  # 数据采集间隔500ms从1000ms优化
    websocket:
      push-interval: 1000  # WebSocket推送间隔1000ms

2. WebSocket节流机制

DataCollectorService中添加:

  • lastPushTimes: 跟踪每个对象的上次推送时间
  • shouldPushWebSocketMessage(): 检查是否应该推送消息
  • 对每个数据处理循环添加节流检查

3. 服务整合优化

解决了之前的SpeedCalculationService Bean冲突问题

  • 删除重复的common包中的服务
  • 增强现有的dataprocessing包中的服务
  • 添加实时速度计算功能

代码变更

1. 数据采集配置

# 数据采集间隔500ms每秒2次
interval: 500

# WebSocket推送节流1000ms每秒1次
websocket:
  push-interval: 1000

2. 节流机制实现

/**
 * 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. 数据处理优化

为三种数据类型(航空器、机场车辆、无人车)都添加了节流检查:

// 节流检查只有达到推送间隔时才发布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. 大部分速度都是0250ms内位置没变化距离为0速度为0

根因分析

核心误区:混淆了数据采集频率和速度计算频率

  • 错误逻辑250ms采集 → 250ms计算速度 → 节流推送
  • 正确逻辑250ms采集 → 缓存位置 → 1000ms计算速度 → 1000ms推送

用户洞察

"我们提高采样频率,为的是获取到数据,而不是为了提高计算频率。速度计算应该是以输出频率来计算。"

修复方案

// 修复前:基于采集频率计算,导致速度异常
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
状态: 已完成