资讯动态

Flink车联网远控预警系统实战 —— 第 1 章 业务全景:远控链路与预警诉求

发布时间:2026/10/14 0:24:32 来源:尧图企业网站定制
Flink车联网远控预警系统实战 —— 第 1 章 业务全景远控链路与预警诉求章节定位专栏第一篇开篇。本章不讲代码先把业务讲透——远控指令在 L3/L2/TBox 三系统间怎么走、留下哪些日志节点、六个时间锚点如何撑起四段耗时、三级结果怎么判定以及最终的预警业务目标。理解了业务链路后面的 Flink 解析、聚合、广播、窗口才有根基。版本基线Apache Flink 2.x Doris 4.x Flink CDC 3.x Kafka 3.x MySQL 8.x DolphinScheduler 3.x章节导读1.1 远控是什么一条指令的跨系统旅程1.2 链路节点全景L3 与 L2 两套日志1.3 六个时间锚点与四段耗时1.4 三级结果判定成功、失败与失败定位1.5 预警业务目标与数据诉求1.6 本章小结与下章预告1.1 远控是什么一条指令的跨系统旅程1.1.1 业务场景用户在手机 APP 上点开空调这条指令要穿过三个系统才能到达车辆并执行┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ APP │────▶│ L3 平台 │────▶│ L2 平台 │────▶│ TBox │ │ (用户) │ │ 调度适配 │ │ 车机通信 │ │ (车机) │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ▲ ▲ ▲ │ └────────────────┴────────────────┴────────────────┘ 结果沿原路返回三个系统各司其职系统职责通俗理解L3 平台接收 APP 请求、指令调度、车型适配、结果汇总“总调度”把用户的活派下去把结果收上来告诉用户L2 平台与车机通信包括唤醒、指令下发、结果回收“通讯员”直接跟车机打交道车机休眠时还负责发短信唤醒TBox车机接收并执行具体指令返回执行结果“干活的”真正去开空调、锁车门1.1.2 为什么需要三个系统为什么不直接 APP → 车机? ✗ 车机在地下车库没信号,需要短信唤醒 ✗ 不同车型协议不同,需要适配层 ✗ 结果要汇总、要重试、要落库,需要调度层 为什么 L2 不直接连 APP? ✗ L2 只管通信,不懂业务(开空调 vs 锁车门的差异) ✗ L3 要做权限校验、频次控制、结果归档 结论: L3 懂业务, L2 懂通信, TBox 懂执行 —— 三层各有不可替代的职责1.1.3 一次远控的完整时序下面是一次开空调的完整往返注意每个节点都会在 Kafka 里留下一条日志用户点按钮 │ ▼ ① APP 发请求给 L3 L3 收到 → ② 整理好指令转发给 L2 │ ▼ ③ 车机可能在休眠,L2 发唤醒短信 短信网关 → 车机被唤醒 │ ▼ ④ L2 把开空调指令下发给车机 TBox 执行 → ⑤ 车机返回空调已打开 │ ▼ ⑥ L2 把结果回传给 L3 L3 汇总 → ⑦ L3 告诉用户空调已打开这 7 步里有 6 步会产生日志节点唤醒短信的两条视车机状态而定。这些节点时间戳就是后面计算耗时、判定结果的全部素材。1.2 链路节点全景L3 与 L2 两套日志整个链路的日志分散在两个 Kafka Topic里L3 平台写cornex_remote_log_l3L2 平台写cornex_remote_log_l2。1.2.1 L3 平台节点4 个节点含义通俗说明APP_TO_L3APP 发起远控请求用户点了开空调请求到达 L3L3_TO_L2L3 把指令转发给 L2L3 处理完把活派给 L2可能多轮先查状态再发指令L2_TO_L3L2 把结果回给 L3L2 从车机拿到结果告诉 L3L3_TO_APPL3 把最终结果回给 APPL3 把结果告诉用户空调已打开L3 日志格式是单行文本2026-10-12 10:15:00.100 [vis-rc-async-LCNTBOX0000000005-745188f0481c4ec1] recv from app RCSXX APP_TO_L3 {symbol:VA24931H001186,cmdType:LOCK} └──── 前23字符时间 ────┘└──────────── []内requestId ──────────────────┘ └─── forward ───┘└────────── data ──────────┘四个关键字段时间戳前 23 个字符格式yyyy-MM-dd HH:mm:ss.SSSrequestId第一对[ ]之间的内容是一次远控的唯一标识forwardRCSXX之后第一个 token即节点名dataJSON含symbolVIN、result等1.2.2 L2 平台节点6 个节点含义通俗说明F_L3L2 收到 L3 的请求L2 接到 L3 派来的活T_SMS发送唤醒短信车机在休眠先发短信唤醒它F_SMS唤醒短信响应车机被唤醒了T_L0L2 把指令下发给 TBoxL2 把具体指令发给车机F_L0TBox 执行完返回结果车机说空调打开了或执行失败T_L3L2 把结果回传 L3L2 把车机的结果汇报给 L3L2 日志格式是JSON{dcm_no:VA24931H001186,tag:T_L0,sessionId:vis-rc-async-LCNTBOX0000000005-745188f0481c4ec1,time:1791771300320}四个关键字段sessionId等于 L3 的 requestId两侧关联的桥梁timeepoch 毫秒字符串tag节点名F_L3 / T_SMS / F_SMS / T_L0 / F_L0 / T_L3dcm_noVIN1.2.3 节点排序按业务状态机不按时间戳节点不是简单按时间排序,而是按业务流程的状态机排序: APP_TO_L3 → L3_TO_L2 → (T_SMS → F_SMS) → T_L0 → F_L0 → L2_TO_L3/T_L3 → L3_TO_APP 即使各节点时间戳因采集延迟有微小偏差,链路顺序仍然正确。 例如 L2_TO_L3 的时间戳可能比 F_L0 早一点(日志写入延迟), 但业务上 F_L0 一定在 L2_TO_L3 之前。这一点很重要——后面 Flink 聚合时我们不按时间戳排序节点而是按 forward 的语义位置写入对应锚点。1.3 六个时间锚点与四段耗时从排序后的节点中提取6 个关键时间点作为所有耗时计算的基础。1.3.1 六个锚点来自 L3 索引的 4 个锚点锚点来自哪个节点取值规则业务含义startAPP_TO_L3取最早用户请求到达 L3 的时刻整个远控的起点firstL3ToL2L3_TO_L2取第一条L3 第一次把请求交给 L2 的时刻lastL2ToL3L2_TO_L3取最后一条L2 最后一次把结果交回 L3 的时刻endL3_TO_APP最终态覆盖L3 把最终结果告诉用户的时刻整个远控的终点来自 L2 索引的 2 个锚点锚点来自哪个节点取值规则业务含义tl0T_L0取最后一轮L2 把指令下发给车机的时刻fl0F_L0取最后一轮车机执行完返回结果的时刻1.3.2 为什么 firstL3ToL2 取第一条、lastL2ToL3 取最后一条一次远控中L3 和 L2 之间可能多轮往返比如先查车辆状态再发控制指令APP_TO_L3 → L3_TO_L2(第1轮:查状态) → L2_TO_L3(第1轮) → L3_TO_L2(第2轮:发指令) → L2_TO_L3(第2轮) → L3_TO_APP ↑取这一条 ↑取这一条 firstL3ToL2 lastL2ToL3firstL3ToL2 取第一条标记L3 第一次把请求交给 L2从此 L3 的活就告一段落lastL2ToL3 取最后一条标记L2 最后一次把结果交回 L3此后轮到 L3 收尾中间所有往返的时间都归 L2 侧L3 只承担开头和结尾两段1.3.3 四段耗时计算总耗时 ctrlTime公式: ctrlTime end - start从用户点按钮APP_TO_L3到 L3 告诉用户结果L3_TO_APP之间的全部时间。缺失处理如果没收到 L3_TO_APPend 为空总耗时记为 null无法计算。L3 平台耗时 l3Time公式: l3Time 前段 后段 前段 firstL3ToL2 - start 后段 end - lastL2ToL3L3 在整个链路中只干两件事——开头把请求整理好交给 L2结尾把 L2 的结果整理好告诉 APP。中间等 L2 和车机执行的时间不算 L3 的。设计意图L3 和 L2 之间可能多轮往返中间所有往返时间都归 L2L3 只计首尾两段。TBox 车机执行耗时 tboxTime公式: tboxTime fl0 - tl0从 L2 把指令下发给车机T_L0到车机执行完返回结果F_L0之间的时间。这是车机真正干活的时间。缺失处理如果 T_L0 或 F_L0 缺失车机耗时记为 null。L2 平台耗时 l2Time残差法公式: l2Time ctrlTime - l3Time - tboxTime (负数则记为 0)L2 耗时不直接从 L2 节点的时间相减得出而是用总耗时减去 L3 和车机的耗时剩余的就是 L2 的。因为 L2 的工作分散在各个节点之间排队、短信唤醒、网络通信、多轮往返很难单独切分。负数清零的原因各节点的时钟和采集时间可能有微小偏差导致残差为负。清零是为了避免显示不合理的数据。1.3.4 耗时关系可视化用户点按钮 L3回复用户 │ │ ▼ ▼ ├─ L3前段 ─┤◄──────────── L2耗时(残差) ────────────►│◄─车机耗时─►│◄─ L3后段 ─►│ │ │ │ │ │ │ L3整理请求│ (L2排队、短信唤醒、网络、往返等) │ 车机干活 │ L3整理结果 │ │ │ │ │ │ start firstL3ToL2 tl0 fl0 lastL2ToL3 end ◄────────────────────── 总耗时 ctrlTime ───────────────────────────────────────► L3耗时 L3前段 L3后段 车机耗时 fl0 - tl0 L2耗时 总耗时 - L3耗时 - 车机耗时负数清零1.3.5 节点缺失对耗时的影响缺失的节点影响的锚点总耗时L3耗时车机耗时L2耗时L3_TO_APP终点end 为空无法计算只有前段不受影响无法计算L3_TO_L2首转发firstL3ToL2 为空正常前段缺失只有后段不受影响偏大L2_TO_L3末回传lastL2ToL3 为空正常后段缺失只有前段不受影响偏大T_L0下发车机tl0 为空正常不受影响无法计算偏大F_L0车机返回fl0 为空正常不受影响无法计算偏大APP_TO_L3起点start 为空无法计算前段缺失不受影响连锁失效核心结论L3_TO_APP 缺失影响最大导致总耗时、L3 后段、L2 耗时三个字段连锁失效。但车机耗时完全不受影响因为它来自 L2 索引的独立节点。1.4 三级结果判定成功、失败与失败定位耗时算完了还要回答两个问题这次远控成功了吗如果失败了问题出在哪1.4.1 三级结果每个系统执行后都会返回自己的结果码形成三级结果层级系统数据来源来源节点取值字段第一级TBox车机L2 索引F_L0result/resultMessage第二级L2 平台L3 索引L2_TO_L3result.statusCode/result.statusMessage第三级L3 平台L3 索引L3_TO_APP最终态result.result/result.msg注意L2 结果有两个来源L2_TO_L3在 L3 索引T_L3在 L2 索引本质是同一个动作L2 把结果告诉 L3分别记录在两个索引中。1.4.2 L2 结果码归一化坑点: L2 返回的 statusCode 为 0 时表示成功,与其它层 1成功 相反! 归一化: L2 的 0 → 统一转成 1成功,其它 → 失败码 如果不归一化,判定时会把 L2 的成功当成失败,整条链路的口径全错。1.4.3 最终结果判定最终成败结论取自L3 平台的结果L3_TO_APP 最终态最终结果值判定说明1成功L3 确认远控执行成功非1失败L3 返回失败码和失败原因没有值未知未收到 L3 的最终结果为什么指令已下发不算最终结果L3 在远控过程中可能发两条 L3_TO_APP 消息消息msg 内容result 值含义是否最终态第 1 条指令已下发1L3 已把指令发出去了但车还没执行完否中间态第 2 条指令执行成功 / 远控失败1/0车辆实际执行结果是“指令已下发只表示 L3 成功转发了指令不代表车辆执行成功。系统用msg字段过滤掉这个中间态只回填真正的最终结果。如果第 2 条始终没来最终结果就一直是空显示未知”。1.4.4 失败节点定位如果远控失败了从最下游车机开始往上游L3依次检查谁先不是成功就定位到谁检查顺序检查什么定位到的节点业务含义1车机结果是否成功TBoxF_L0车机执行失败车的问题2L2 结果是否成功L2L2_TO_L3L2 平台处理失败L2 的问题3L3 结果是否成功L3L3_TO_APPL3 平台处理失败L3 的问题为什么从下游开始查指令按 APP→L3→L2→TBox 的顺序往下传。如果车机执行失败了L2 和 L3 后续的结果可能是失败也可能是超时未知但根因是车机。从下游开始查可以精确定位到第一个出问题的环节避免误判。1.4.5 未收到 L3 最终结果时的兜底当 L3 最终结果为空未知时失败定位只能检查车机和 L2 两级情况车机结果L2 结果L3 结果能否定位定位到车机失败非1-空能TBox车机问题L2 失败“1”非1空能L2L2 问题都成功但 L3 未知“1”“1”空不能显示未知需人工确认1.4.6 典型场景判定速查场景车机结果L2 结果L3 结果最终判定失败节点全链路成功111成功-车机执行失败非1-非1失败TBoxL2 平台超时1非1非1失败L2L3 回复 APP 失败11非1失败L3未收到最终结果11空未知-车机和 L2 都失败非1非1非1失败TBox下游优先1.5 预警业务目标与数据诉求15.1 预警要解决什么问题现状: 每天几万次远控,偶发性的失败/超时无人感知 出了问题用户投诉后才被动排查 缺乏分钟级的失败率/超时率监控手段 预警目标: ① 分钟级统计各采样区间的远控失败率、超时率 ② 配置化阈值: 失败率超 X% 或超时率超 Y% 即触发 ③ 推送: 楚能 OA 邮件通知运维团队 ④ 配置热更新: 调阈值/采样区间不用重启作业1.5.2 预警统计口径指标公式说明远控失败率失败次数 / 远控总次数 × 100采样区间内远控超时率超时次数 / 远控总次数 × 100超时 失败且总耗时 ≥ 30000ms采样车辆数区间内去重 VIN 数同一辆车多次远控只算 1 辆失败车辆数区间内至少失败 1 次的去重 VIN 数1.5.3 配置驱动的采样策略预警配置表t_cn_remote_warning_config存于 MySQL的关键字段字段说明使用方min_sample_count最少采样次数不足不输出大数据侧校验样本数sample_interval_valuesample_interval_unit采样回看区间如 30 分钟大数据侧确定统计窗口remote_monitor_frequency失败率阈值TSP 侧比对remote_duration超时率阈值TSP 侧比对push_alert_valuepush_alert_unit推送频率节流TSP 侧控制不重复推送is_enable是否启用大数据侧仅统计启用配置1.5.4 大数据侧与 TSP 侧的职责边界┌──────────────────────────────────────────────────────┐ │ 大数据侧(Flink Doris): │ │ ① 按 requestId 聚合出单次远控的结果与耗时 │ │ ② 每分钟按配置区间统计失败率/超时率/样本数 │ │ ③ 校验样本数(min_sample_count),不足不写入 │ │ ④ 写入 ads_vehicle_remote_warning_stat │ │ ✗ 不做阈值比对 │ │ ✗ 不做推送 │ └──────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────┐ │ TSP 应用侧: │ │ ① 拿统计记录,与 remote_monitor_frequency 比对 │ │ ② 按 push_alert_value/unit 做推送频率节流 │ │ ③ 按 push_type/push_account 推送 OA / 邮件 │ └──────────────────────────────────────────────────────┘为什么阈值判定交给 TSP阈值规则可能频繁调整今天 5%明天 3%如果放在 Flink 作业里每次调整都要重启作业。TSP 侧读配置比对改阈值零延迟生效。大数据侧只保证统计数据准确。1.5.5 数据链路全景┌──────────────┐ ┌──────────────┐ ┌─────────────────────┐ │ Kafka L3 │ │ Kafka L2 │ │ MySQL 预警配置表 │ │ (文本日志) │ │ (JSON 日志) │ │ (FlinkCDC 实时同步) │ └──────┬───────┘ └──────┬───────┘ └──────────┬──────────┘ │ │ │ └────────┬────────┘ │ ▼ ▼ ┌────────────────────────────────────────────┐ │ Flink 实时计算 │ │ 解析 → 按 requestId 聚合 → 结果判定耗时 │ │ → DWD 明细 → 广播配置 窗口聚合 → ADS 统计 │ └────────────────────┬───────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ Doris DWD ADS 表 │ └──────────────┬──────────────┘ │ ▼ ┌─────────────────────────────┐ │ TSP 阈值判定 推送 │ └─────────────────────────────┘1.6 本章小结与下章预告本章小结┌──────────────────────────────────────────────────────────────┐ │ 第 1 章 要点回顾 │ └──────────────────────────────────────────────────────────────┘ ✓ 业务链路: APP → L3(调度) → L2(通信) → TBox(执行), 结果沿原路返回;三层各有不可替代的职责 ✓ 两套日志: L3 文本日志(4 节点) L2 JSON 日志(6 节点), 通过 requestId sessionId 关联 ✓ 六锚点: start / firstL3ToL2(取首) / lastL2ToL3(取尾) / end / tl0 / fl0;多轮往返时中间时间归 L2 ✓ 四耗时: ctrlTime(end-start) / l3Time(前段后段) / tboxTime(fl0-tl0) / l2Time(残差法负数清零) ✓ 三级判定: L3 最终态优先 → TBox/L2 兜底 → 未知; L2 statusCode0 需归一化为 1;中间态指令已下发需过滤 ✓ 预警目标: 分钟级失败率/超时率统计,配置化阈值, 大数据侧只管统计,阈值比对与推送交给 TSP下章预告第 2 章 技术选型与架构总览业务讲完了该搭技术骨架了。本章回答三个问题为什么选 Flink Doris Flink CDC Kafka MySQL DolphinScheduler 这六个组件它们在链路中各自承担什么职责全链路拓扑长什么样同时亮出本课程贯穿始终的生产硬约束清单——这些硬约束会在后续每一章的代码里反复出现。官方参考资料Apache Flink DocumentationApache Doris DocumentationFlink CDC Documentation本章实战代码清单序号内容说明1远控链路三系统职责划分1.12L3(4 节点) L2(6 节点)日志字段解析1.23六锚点取值规则与多轮往返处理1.3.1~1.3.24四段耗时计算公式与缺失处理1.3.35三级结果判定与失败定位逻辑1.46预警统计口径与大数据/TSP 职责边界1.5

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑