# RMDC-Exchange-Hub 指令执行时间计算规范 ## 1. 概述 本文档定义了 RMDC-Exchange-Hub 模块中指令执行全生命周期的时间追踪与计算规范。 --- ## 2. 时间点定义 ### 2.1 指令生命周期时间点 ```mermaid sequenceDiagram participant BM as 业务模块 participant EH as Exchange Hub participant MQTT as MQTT Broker participant WD as Watchdog participant EX as 执行体 Note over EH: ① created_at
指令创建时间 BM->>EH: 发起指令请求 Note over EH: ② sent_at
发送到MQTT时间 EH->>MQTT: Publish指令 Note over WD: ③ acked_at
Watchdog确认接收 MQTT->>WD: 推送指令 WD-->>EH: (可选) ACK确认 Note over WD: ④ started_at
开始执行时间 WD->>EX: 调用执行体 Note over EX: ⑤ start_time (ms)
执行体内部开始 EX->>EX: 执行指令... Note over EX: ⑥ end_time (ms)
执行体内部结束 EX->>WD: 返回结果 Note over WD: ⑦ 消息上行 WD->>MQTT: ExecResult上行 Note over EH: ⑧ received_at
Exchange Hub接收 MQTT->>EH: 推送结果 Note over EH: ⑨ completed_at
指令完成时间 ``` ### 2.2 时间点存储位置 | 时间点 | 字段名 | 存储表 | 类型 | 说明 | |-------|-------|-------|------|------| | 指令创建 | `created_at` | command_trackers | TIMESTAMP | 自动记录 | | 发送到MQTT | `sent_at` | command_trackers | TIMESTAMP | 调用MQTT Publish时记录 | | Watchdog确认 | `acked_at` | command_trackers | TIMESTAMP | 收到ACK消息时记录 | | 开始执行 | `started_at` | command_trackers | TIMESTAMP | 收到running状态时记录 | | 执行开始(内部) | `start_time` | command_results | INT64 (ms) | Watchdog侧记录 | | 执行结束(内部) | `end_time` | command_results | INT64 (ms) | Watchdog侧记录 | | 结果接收 | `received_at` | command_results | TIMESTAMP | Exchange Hub接收结果时记录 | | 指令完成 | `completed_at` | command_trackers | TIMESTAMP | 更新为终态时记录 | --- ## 3. 时间耗时计算公式 ### 3.1 核心耗时指标 | 指标名称 | 计算公式 | 单位 | 含义 | |---------|---------|------|------| | **指令下发耗时** | `acked_at - sent_at` | ms | 指令从Exchange Hub到达Watchdog的网络耗时 | | **指令执行耗时** | `end_time - start_time` (或 `duration`) | ms | 指令在执行体内的实际执行时间 | | **指令上行耗时** | `received_at - end_time` | ms | 执行结果从Watchdog返回Exchange Hub的耗时 | | **总体耗时** | `completed_at - sent_at` | ms | 从发送到完成的总时间 | ### 3.2 扩展耗时指标 | 指标名称 | 计算公式 | 单位 | 含义 | |---------|---------|------|------| | 排队耗时 | `sent_at - created_at` | ms | 指令在Exchange Hub等待发送的时间 | | 处理准备耗时 | `started_at - acked_at` | ms | Watchdog接收到开始执行的准备时间 | --- ## 4. 数据结构定义 ### 4.1 CommandTracker 时间字段 ```go type CommandTracker struct { // ... 其他字段 ... // 时间追踪字段 SentAt *time.Time // 发送到MQTT时间戳 AckedAt *time.Time // Watchdog确认接收时间戳 StartedAt *time.Time // 开始执行时间戳 CompletedAt *time.Time // 完成时间戳 CreatedAt time.Time // 创建时间 TimeoutAt *time.Time // 超时时间 } ``` ### 4.2 CommandResult 时间字段 ```go type CommandResult struct { // ... 其他字段 ... // 执行时间字段 (来自Watchdog) StartTime int64 // 执行开始时间戳(ms) EndTime int64 // 执行结束时间戳(ms) Duration int64 // 执行时长(ms) // 上行时间字段 (Exchange Hub记录) ReceivedAt time.Time // 结果接收时间 UploadDuration int64 // 上行耗时(ms) = ReceivedAt - EndTime } ``` ### 4.3 时间详情DTO ```go // CommandTimeDurations 指令时间耗时详情 type CommandTimeDurations struct { DeliveryDuration int64 `json:"delivery_duration"` // 下发耗时(ms) ExecDuration int64 `json:"exec_duration"` // 执行耗时(ms) UploadDuration int64 `json:"upload_duration"` // 上行耗时(ms) TotalDuration int64 `json:"total_duration"` // 总体耗时(ms) QueueDuration int64 `json:"queue_duration,omitempty"` // 排队耗时(ms) } ``` --- ## 5. API响应格式 ### 5.1 查询指令响应增强 ```json { "code": 0, "message": "success", "data": { "command_id": "k8s_exec-proj_001-241222114530", "project_id": "proj_001", "status": "success", "created_at": "2024-12-22 11:45:30", "completed_at": "2024-12-22 11:45:35", "time_durations": { "delivery_duration": 150, "exec_duration": 4500, "upload_duration": 120, "total_duration": 4850 }, "result": { ... } } } ``` ### 5.2 同步指令响应 ```json { "code": 0, "message": "success", "data": { "command_id": "k8s_exec-proj_001-241222114530", "status": "success", "exit_code": 0, "output": "...", "duration": 4500, "time_durations": { "delivery_duration": 150, "exec_duration": 4500, "upload_duration": 120, "total_duration": 4850 } } } ``` --- ## 6. 计算实现伪代码 ```go // CalculateCommandDurations 计算指令时间耗时 func CalculateCommandDurations( tracker *entity.CommandTracker, result *entity.CommandResult, ) *dto.CommandTimeDurations { durations := &dto.CommandTimeDurations{} // 1. 下发耗时 if tracker.SentAt != nil && tracker.AckedAt != nil { durations.DeliveryDuration = tracker.AckedAt.Sub(*tracker.SentAt).Milliseconds() } // 2. 执行耗时 (优先使用Watchdog计算值) if result != nil && result.Duration > 0 { durations.ExecDuration = result.Duration } else if result != nil && result.StartTime > 0 && result.EndTime > 0 { durations.ExecDuration = result.EndTime - result.StartTime } // 3. 上行耗时 if result != nil && result.EndTime > 0 { receivedAtMs := result.ReceivedAt.UnixMilli() durations.UploadDuration = receivedAtMs - result.EndTime } // 4. 总体耗时 if tracker.SentAt != nil && tracker.CompletedAt != nil { durations.TotalDuration = tracker.CompletedAt.Sub(*tracker.SentAt).Milliseconds() } // 5. 排队耗时 (可选) if tracker.SentAt != nil { durations.QueueDuration = tracker.SentAt.Sub(tracker.CreatedAt).Milliseconds() } return durations } ``` --- ## 7. 注意事项 1. **时区统一**: 所有时间必须使用统一时区 (Asia/Shanghai, UTC+8) 2. **精度要求**: 毫秒级精度,int64存储 3. **空值处理**: 计算时需检查时间字段是否为nil 4. **Watchdog时间**: `start_time`/`end_time` 由Watchdog本地时间生成,可能存在时钟偏差