--- tags: [] aliases: - 2.4.5 端到端延迟遥测 (End-to-End Latency Telemetry) date created: 星期一, 十一月 24日 2025, 4:49:40 下午 date modified: 星期一, 十一月 24日 2025, 4:50:25 下午 --- # 2.4.5 端到端延迟遥测 (End-to-End Latency Telemetry) 这是系统的“后视镜”。它不再用于实时的流控反馈(因为抢占逻辑已移除),而是作为核心的**运维监控指标 (Observability Metric)**。它回答了一个终极问题:“现在的网络和负载状况下,用户看到的数据到底是多久以前的?” ## 一、 约束输入与对齐 (Constraints & Alignment) 基于 TDP-2.4-DIST(分布式补丁)和之前确立的基线,我们需对齐以下硬性约束: 1. **时钟基准 (Time Reference)**:所有计算必须基于**统一的 UTC 时间**。服务器(发送端)和显控(接收端)均已通过总控服务器授时(NTP/PTP),误差假设在可控范围内(如 < 10ms)。 2. **闭环路径 (Feedback Path)**:显控端计算出的延迟数据,需要回传给服务器端的 `MonitoringModule`,以便在统一的监控大屏上展示。 3. **统计意义 (Statistical Significance)**:单帧的延迟没有意义(可能是网络抖动),我们关注的是 **P99 延迟** 和 **平均延迟** 的趋势。 --- ## 二、 权衡分析与选项呈现 (Trade-off Matrix) ### 议题 1:回传通道选择 (Feedback Channel) |**选项**|**A. 双向 UDP (Bidirectional UDP)**|**B. 带外 TCP/HTTP (Out-of-Band HTTP) (推荐)**| |---|---|---| |**机制**|显控端通过 UDP 向服务器的特定端口发回 `Ack/Stats` 包。|显控端调用服务器提供的 REST API 上报统计数据。| |**实时性**|**高**。|**低**(秒级)。| |**耦合度**|**高**。需要在 `DisplayController` 中增加接收逻辑,破坏了其“单向数据泵”的纯粹性。|**低**。直接复用 `API Gateway` 和 `MonitoringModule` 的现有接口。| |**适用性**|实时流控(已废弃)。|**长周期监控与健康分析**。| ### 议题 2:指标计算策略 (Calculation Strategy) |**选项**|**A. 瞬时值上报 (Instant Reporting)**|**B. 客户端聚合 (Client-Side Aggregation) (推荐)**| |---|---|---| |**机制**|每收到一包数据,就计算 `Now - Ts` 并上报。|客户端维护 1 分钟的 Histogram,计算 P99/Avg,定期上报汇总值。| |**带宽开销**|**高**。回传流量巨大,浪费网络。|**极低**。每分钟仅几百字节。| |**价值**|包含噪声,难以分析。|**高价值**。直接反映一段时间内的服务质量 (QoS)。| --- ## 三、 基线确立与实施规范 为了构建一个闭环的监控体系,我们确立 **B. 带外 HTTP 回传** + **B. 客户端聚合** 为基线。 ### 1. 核心指标定义 (Metrics Definition) - **E2E Latency (Glass-to-Glass)**: $\text{Latency} = T_{Client\_Recv} - T_{Server\_Gen}$ - $T_{Server\_Gen}$: `TrackDataBatch.timestamp_us` (UTC)。 - $T_{Client\_Recv}$: 显控端收到 UDP 包时的本地系统时间 (UTC)。 - **意义**: - **正常范围**:< 50ms (局域网) / < 200ms (广域网)。 - **异常推断**:如果 Latency 突然飙升但没有丢包,说明发生了 **Bufferbloat (缓冲区膨胀)**,可能是 2.4.4 的节流机制介入过晚,或者网络设备队列堵塞。 ### 2. 显控端实现规范 (Client-Side Implementation) 显控端应启动一个后台任务,负责统计和上报: ```cpp // 伪代码:客户端遥测聚合器 class TelemetryAggregator { // 统计窗口数据 (1Hz 刷新) std::vector latency_samples; uint64_t packet_loss_count = 0; public: void onPacketReceived(const TrackDataBatch& batch) { uint64_t now = GetUtcTimeUs(); int64_t latency = now - batch.timestamp_us; // 过滤掉因为时钟不同步导致的负值 if (latency > 0) latency_samples.push_back(latency); } // 每 60 秒执行一次上报 void reportLoop() { while (running) { sleep(60); // 1. 计算统计值 double avg = CalculateAvg(latency_samples); double p99 = CalculateP99(latency_samples); // 2. 构建 JSON 报告 json report = { {"station_id", station_id}, {"latency_p99_ms", p99 / 1000.0}, {"latency_avg_ms", avg / 1000.0}, {"packet_loss_rate", CalculateLossRate()} }; // 3. 调用 API 上报 (复用 05_数据完整性与可靠性.md 定义的接口) HttpPost("http://server_ip:8080/api/v1/metrics/client", report); // 4. 重置窗口 latency_samples.clear(); } } }; ``` ### 3. 服务端处理基线 - **接收者**:`API Gateway` 接收 HTTP POST 请求。 - **路由**:转换为 `ClientMetricsUpdateEvent` 发布到事件总线。 - **消费者**:`MonitoringModule` 订阅该事件,并将指标存储到时序数据库(如 Prometheus/InfluxDB),用于生成 Grafana 仪表盘。 - **告警**:如果 `latency_p99 > 500ms` 持续 3 分钟,触发 **"Network Degradation"** 告警。 ---