7.8 KiB
7.8 KiB
飞机GIS链路稳定性与前端显示优化审查报告
- 审查日期: 2026-03-02
- 审查方式: 静态代码审查(未启动服务、未运行测试)
- 审查范围: GIS接收 -> 速度/角度计算 -> 平滑/防跳点 -> WebSocket下发
1. 审查结论(先说结论)
当前链路已经有“去抖 + 限跳 + 合并推送”的基础能力,但距离“专业级稳定显示”还有关键缺口。
最主要风险集中在3点:
- 处理线程与采集线程并发写同一状态对象,存在旧数据回写覆盖新数据的可能,会导致前端回跳、抖动。
- 非飞机目标在“异常跳点重获”时采用“丢2次后直接接受原始点”的策略,仍可能出现突然跳远。
- 速度/航向在不可计算时使用固定默认值(40/25/20 km/h, heading=0),会向前端输出伪物理状态。
2. 关键问题清单(按严重度)
P0-1 并发回写导致轨迹回跳(高风险)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:122qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:201qaup-collision/src/main/java/com/qaup/collision/common/config/SchedulerConfig.java:19
- 现象: 先拍快照再计算,计算后再
put回缓存;在多线程调度下,采集线程可能已经写入更新位置,随后被处理线程“旧快照对象”覆盖。 - 直接后果: 前端位置回退、路径折返、局部抖动。
P0-2 非飞机对象“重获”策略仍可能瞬移(高风险)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java:522qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java:533qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java:536
- 现象: 非飞机跳点超限时,前2次丢弃,第3次直接接受原始坐标。
- 直接后果: 仍可能“一下子跳出去很远”,尤其在短时GPS漂移或上游坐标抖动时。
P0-3 输出伪速度/伪航向(高风险)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:170qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:190qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:234
- 现象: 速度/方向算不出来时,直接下发默认速度和朝向(40/25/20、0度)。
- 直接后果: 前端若按速度做插值,会出现“方向突变”或“虚假运动”。
P1-1 飞机同批去重只按 flightNo,时间戳并列时无稳定择优(中高)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.java:415qaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.java:425qaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.java:438
- 现象: 同 flightNo 多点时只看
sourceTimestampMs,并列或空时间戳时选择不稳定。 - 直接后果: 同一周期内点位可能来回切换,路径“绕一下”或折线异常。
P1-2 速度历史缓存缺少生命周期对齐(中高)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/SpeedCalculationService.java:32qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/SpeedCalculationService.java:174qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/SpeedCalculationService.java:181
- 现象:
positionHistory长驻;对象在活跃缓存被清理后,速度历史未同步清理。 - 直接后果: 对象重现时可能引用过旧历史,造成首帧速度/方向不稳定。
P1-3 时间戳单位双轨(微秒/毫秒)增加前端误用风险(中)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/websocket/event/PositionUpdateEvent.java:32qaup-collision/src/main/java/com/qaup/collision/dataprocessing/service/DataProcessingService.java:260qaup-collision/src/main/java/com/qaup/collision/websocket/message/UniversalMessage.java:28
- 现象: 外层消息
timestamp为微秒,payloadtimestamp为毫秒。 - 直接后果: 前端若误用外层时间做动画插值,会出现时间比例错误和轨迹异常。
P2-1 非飞机滤波参数未配置化落地,依赖代码默认值(中)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java:58qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java:130qaup-admin/src/main/resources/application-dev.yml:80qaup-admin/src/main/resources/application-prod.yml:58
- 现象: 平滑参数大量由
@Value默认值承载,环境缺少显式配置基线。 - 直接后果: 不同机场/地图比例下难以精细调参,稳定性受限。
P2-2 x/y 与 lat/lon 语义依赖约定,缺少强校验(中)
- 证据:
qaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.java:361qaup-collision/src/main/java/com/qaup/collision/datacollector/service/VehicleStatusAggregationService.java:64
- 现象: 某些来源使用 x/y,代码按“x=lat,y=lon”解释;若上游调整语义,容易引入反转问题。
- 直接后果: 轨迹漂移、跳点、方向异常。
3. 专业级优化方案(不改代码版建议)
P0 立即改(先止血)
- 统一“位置状态单写者”模型。
- 采集线程只写原始缓存,处理线程只读不回写位置。
- 速度/航向另设派生字段缓存,避免覆盖位置主状态。
- 调整非飞机重获策略。
- 禁止“第3次直接接收原始点”;改为“限步过渡”直到收敛。
- 这样可消除大跳点。
- 去掉默认伪速度/伪航向下发。
- 不可计算时下发
null或valid=false标记。 - 前端接到无效值时保持上一帧方向,位置只按真实点更新。
- 不可计算时下发
P1 本周内改(提升稳定)
- 飞机去重引入稳定择优键。
- 建议排序键:
sourceTimestampMs->trackNumber-> 与上一点距离最小。
- 建议排序键:
- 速度历史增加TTL并与对象清理联动。
- 对象清理时同步
clearHistory(objectId)。
- 对象清理时同步
- 统一消息时间语义。
- 约定只让前端使用
payload.timestamp(ms)做运动插值。 - 外层时间仅用于日志/排序。
- 约定只让前端使用
P2 持续优化(工程化)
- 把
websocket.position.filter.*全量放入application-*.yml,分环境调参。 - 增加坐标语义守卫。
- 对 x/y 来源记录 schema 版本并做运行时一致性检测。
- 输出质量指标。
- 每对象统计
drop_rate,outlier_count,max_step_meter,reacquire_count。
- 每对象统计
4. 前端“专业级稳定显示”验收指标(建议)
- 单帧位移上限: 非飞机 <= 20m(可按业务调),飞机 <= 80m。
- 跳点率:
outlier_drop / total_points < 1%。 - 抖动率: 静止目标在30秒窗口内位移标准差 <= 1m。
- 轨迹连续性: 不允许出现“反向回跳再前进”锯齿(除非上游真实回退)。
- 时间一致性: 前端插值仅使用毫秒时间戳,严禁混用微秒。
5. 其它观察
- 已抽查关键文件编码均为 UTF-8 无 BOM,编码规范执行良好。
- 发现调试日志以
error级别输出的临时内容,建议后续清理,避免掩盖真实异常。
6. 结语
该项目已经具备基础防抖和限跳框架,但要达到你要求的“前端稳定、专业级显示”,核心是先解决并发回写与重获瞬移策略,再统一速度/时间语义。按本报告的 P0 -> P1 顺序推进,可以明显降低“跳出去很远、路径绕行、频繁抖动”问题。