
随着车联网规模化落地,车辆终端数量持续增长,状态上报、事件告警、远程控制等业务对云端架构提出了更高要求:
本文以车辆低电量告警为例,演示如何通过 TDMQ MQTT + 云函数 SCF 构建事件驱动的车辆状态智能响应链路,实现从设备上报、消息触发、函数处理到指令回传的高效闭环。
方案架构:TDMQ MQTT 与 SCF 如何协同
车端与云端的通信通常包含两类形态,它们对架构的诉求差异很大:

两者通过 MQTT 触发器无缝衔接,可以把车端状态变化直接转化为云端业务响应。
TDMQ MQTT
MQTT 是基于发布/订阅模式的轻量级通信协议,构建于 TCP/IP 之上,天然适合车机、传感器等资源受限的终端设备。腾讯云 TDMQ MQTT 是面向物联网、车联网 等场景打造的高可用 MQTT 消息队列服务:
Topic Filter
MQTT 协议定义了带通配符的订阅方式:+ 匹配单层路径、# 匹配多层路径。例如订阅 sh/tcu/+/battery 可一次性接收所有车辆的电量事件,无需在应用层做分流,TDMQ MQTT 在服务端完成过滤与投递。
云函数 SCF
腾讯云云函数(SCF)是事件驱动的无服务器计算服务,能够由 MQTT 消息触发并按需执行,无需开发者关心底层服务器部署、扩容与运维。在车联网场景中,SCF 可根据车辆状态上报实时触发告警判断、指令生成等后续业务流程,并根据消息流量自动伸缩;同时,不同业务逻辑可拆分为独立函数,围绕 MQTT Topic 解耦演进。
整体架构:从车端上报到指令下发
下图展示了一条完整的事件驱动链路,重点关注图中标注的四个阶段——它们分别由车端 SDK、TDMQ MQTT、SCF、HTTP API 承担,互相之间通过 Topic 解耦。

sh/tcu/{vin}/battery),同时订阅下行控制 Topic(如 sh/tcu/{vin}/command)接收云端指令。sh/tcu/+/battery,即可匹配所有车辆的电量事件。新增或下线消费方对发布端完全无感——这是整条架构 松耦合 的关键。sh/tcu/{vin}/command),车端 TCU 实时收到并执行。至此,车辆状态感知、云端决策与车端执行形成完整的事件驱动响应闭环。
实战演示:车辆低电量告警
场景介绍
当车辆 TCU 检测到电量不足时,将电量状态通过指定 Topic 发送到 TDMQ MQTT,下游多个云函数监听并响应。不同云函数配置不同 Topic Filter 和消息属性匹配条件,灵活实现各自的服务,例如:
本演示聚焦第三个场景,用一个最小可运行的例子串起整条链路:
目标:电量 ≤ 30% 时云端自动把空调降档;≤ 10% 时直接关空调。
Topic 路由
角色 | Topic | 说明 |
|---|---|---|
上报 | sh/tcu/VIN001/battery | TCU 上报电量数据 |
触发器 | sh/tcu/+/battery → BatteryGuard() | 判断电量,调节空调 |
下发 | sh/tcu/VIN001/command | TCU 执行控制指令 |
组件与运行环境
组件 | 语言 | 职责 |
|---|---|---|
TCU Emulator | Rust | 模拟车机 TCU,上报电量并接收控制指令 |
Battery Guard | Java(云函数) | 消费电量事件,判断阈值并下发空调控制指令 |
前端展示页 | JavaScript | 模拟手机小程序,实时展示电量变化 |
TCU Emulator — 车端模拟器(Rust)
TCU Emulator 通过 MQTT Rust SDK 与 TDMQ MQTT 通信,实现电量上报与指令接收。
程序入口(main.rs):配置 MQTT 连接并启动模拟器。
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let vin = "VIN001";
// 1. 拼接 MQTT 接入点(mqtts 表示走 TLS)
let access_point = format!(
"mqtts://mqtt-xxx.tencenttdmq.com:8883?client_id={}", vin
);
let mut opts = MqttOptions::parse_url(&access_point)?;
opts.set_keep_alive(Duration::from_secs(30)); // 30s 心跳保活
opts.set_credentials("root", "password"); // 鉴权(生产环境请用密钥)
// 2. 启动模拟器:内部循环上报 + 订阅控制指令
let mut emu = TcuEmulator::new(vin.to_owned(), opts);
emu.run().await?;
Ok(())
}数据上报循环(lib.rs):每秒上报一次电量,电量随空调功率消耗递减。
pub async fn run(&mut self) -> anyhow::Result<()> {
// 订阅控制指令 Topic(接收云端下发的 ac_power 指令)
let command_topic = format!("sh/tcu/{}/command", self.vin);
self.client.subscribe(command_topic, QoS::AtLeastOnce).await?;
while self.battery > 0 {
tokio::time::sleep(Duration::from_secs(1)).await;
// 电量按当前空调档位递减,模拟真实耗电
self.battery -= self.ac_power.load(Ordering::Relaxed);
let status = BatteryStatus { battery: self.battery };
// 发布到 sh/tcu/VIN001/battery(此处省略发布细节)
}
Ok(())
}接收云端指令:解析 MQTT 消息,动态调整空调功率。
fn process_event(event: Event, ac_power: &Arc<AtomicU8>) {
if let Incoming(Packet::Publish(publish)) = event {
if let Ok(cmd) = serde_json::from_slice::<Command>(&publish.payload) {
info!("收到控制指令: {:?}", cmd);
// 用原子变量更新空调档位,主循环下一秒生效
ac_power.store(cmd.ac_power, Ordering::Relaxed);
}
}
}Battery Guard — 云端响应函数(Java)
Battery Guard 是 Java 云函数。函数入口接收 MqttEvent(触发消息)和 Context(运行上下文):
public class Main {
public String mainHandler(MqttEvent event, Context context) {
logger.info("request-id={}", context.getRequestId());
trySavePower(event);
return objectMapper.writeValueAsString(event);
}
}核心逻辑:根据电量决定响应策略。
private static void trySavePower(MqttEvent event) {
for (Record record : event.getRecords()) {
BatteryStatus status = objectMapper.readValue(
record.getBody(), BatteryStatus.class);
if (status.getBattery() <= 10) {
turnOffAc(record); // ≤ 10%:关闭空调,保续航
} else if (status.getBattery() <= 30) {
savePower(record); // ≤ 30%:降低空调功率
}
}
}决策策略对照
电量范围 | 云函数动作 | 下发指令 | 状态 |
|---|---|---|---|
> 30% | 不处理 | — | 正常 |
10% ~ 30% | savePower() | {"ac_power": 1} | 省电 |
≤ 10% | turnOffAc() | {"ac_power": 0} | 紧急 |
控制指令发布:通过 HTTP 接口发布到 TDMQ MQTT,路由回 TCU。
static void publish(Record record, int targetAcPower) {
String host = System.getenv("HOST");
// 由上行 Topic 推导下行 Topic:sh/tcu/VIN001/battery → sh/tcu/VIN001/command
String topic = record.getProps().get("firstTopic")
+ "/" + record.getProps().get("secondTopic");
String commandTopic = topic.substring(0, topic.lastIndexOf('/') + 1) + "command";
String url = String.format("https://%s/topics/%s?qos=1",
host, URLEncoder.encode(commandTopic));
Command cmd = new Command();
cmd.setAcPower(targetAcPower);
// HTTP POST 发送(细节略)
}这里的 HTTP 仅用于云函数向 TDMQ MQTT 发布下行控制消息;车端上行仍然通过 MQTT SDK 直连,二者职责不同。
前端展示页面
一个轻量 HTML 页面通过 MQTT WebSocket 订阅电量 Topic,实时展示状态变化:
client.on('message', (topic, message) => {
if (topic.endsWith('command')) return; // 跳过控制指令
const battery = JSON.parse(new TextDecoder().decode(message));
setLinearProgress(battery.battery); // 更新电量进度条
});部署与运行效果
sh/tcu/+/battery、sh/tcu/+/commandroot/password)sh/tcu/+/battery[00:01] INFO TCU Emulator started, VIN=VIN001, battery=100%
[00:02] INFO Battery: 98% → published to sh/tcu/VIN001/battery
[00:12] INFO Battery: 48% → published
[00:18] WARN Battery: 28% ≤ 30% threshold
[00:18] SCF savePower() triggered → ac_power: 2 → 1
[00:18] OK Command published: {"ac_power":1} → sh/tcu/VIN001/command
[00:19] INFO TCU received command: ac_power=1, 空调已降档
[00:25] ALERT Battery: 8% ≤ 10% threshold
[00:25] SCF turnOffAc() triggered → ac_power: 1 → 0
[00:25] OK Command published: {"ac_power":0} → sh/tcu/VIN001/command
[00:26] INFO TCU received command: ac_power=0, 空调已关闭链路验证:电量 ≤ 30% 时 SCF 自动触发 savePower(),空调从 2 档降到 1 档;≤ 10% 时触发 turnOffAc(),空调关闭。指令经 MQTT 路由回 TCU 并立即生效,前端同步更新。
方案优势
延伸场景:不止于车联网
MQTT 负责"连接万物",云函数负责 "响应万事"。TDMQ MQTT + SCF 的事件驱动架构同样适用于其他需要 "海量接入 + 弹性响应"的物联网场景,如智能家居、智能零售、工业物联网等。

如果您的业务也有相关需求,欢迎在评论区留下您的使用场景和问题。
欢迎加入腾讯云 TDMQ MQTT 交流群

往期推荐
TDMQ MQTT 铂金版正式上线!全组件独占,最高支持100万 TPS,1000万连接数!
A2A over MQTT:腾讯云 TDMQ 创新 Agent 协作新模式
3-4月产品月报 | CKafka 公网架构与管理能力全面升级,RocketMQ 5.x 集群能力增强
百万级延迟消息稳定投递 - TDMQ Pulsar 的新解法:多级时间轮

扫描下方二维码关注本公众号,
了解更多微服务、消息队列的相关信息!

戳 👇 阅读原文,了解 腾讯云 TDMQ MQTT 更多信息。