Device Agent:一句话,让任意 IoT 设备成为 AI Agent|查看详情 →

EMQX MQTT Streams 和 NATS JetStream 对比:谁更适合持久化设备遥测

EMQX TeamEMQX Team
2026-7-22产品
EMQX MQTT Streams 和 NATS JetStream 对比:谁更适合持久化设备遥测

如果你正在从多台设备持续采集数据,仅依靠实时发布订阅功能已经无法满足需求。业务需要留存历史数据、支持事后回放:下个月新上线的服务,既要能回放传感器今天上报的全部数据,也要在线上部署出现故障时,从指定时间点重新处理数据。这就是持久化消息流。

在基于 MQTT 的业务场景里,想要实现持久化的消息流,普遍做法是在 broker 后端部署 Kafka,再将消息桥接转发过去。

NATS 将持久化的流式能力内置到服务端,命名为 JetStream;EMQX 则在消息网关内部集成了同款能力,也就是 EMQX MQTT Streams。

过去必须依赖 Kafka 才能完成的数据存储与回放,现在可以直接在消息网关内部实现。

两者的流式处理层看起来大同小异,真正的区别在于它们各自所处的系统生态。

EMQX 是一款功能完备的 MQTT 消息中间件,设备集群依赖于流处理层周围的一系列 MQTT 特性保障:设备离线时的遗嘱消息、客户端重连后立即获取当前状态的保留消息、面向单客户端的持久会话,以及对不允许丢失或重复的消息提供的 QoS 2 级别保证。

NATS 则是一个云原生消息系统,在流处理和请求-响应模式方面表现出色,但它面向服务间通信设计,并不原生支持物联网设备所需的各类保障机制。

本文将分别基于两套系统搭建完全相同的持久化遥测场景,各自使用原生客户端接入,并对比它们在流处理层本身以及配套设备能力上的相同点与差异点。

完整示例代码已公开:github.com/emqx/emqx-streams-demo

JetStream 简介

JetStream 是 NATS 服务器内置的持久化层。启用后,同一个处理发布/订阅的服务器还能为你提供:绑定到主题的持久化数据流、可追踪自身消费位置并在确认丢失时重新投递的消费者、键值存储、对象存储,以及工作队列保留模式(消息一经消费者确认即被删除)。发布者去重是内置功能:只需打上 Nats-Msg-Id 头部,服务器就会在可配置的时间窗口内丢弃重复消息。

JetStream 的消费与生产均通过使用 NATS 协议的原生客户端完成,无需任何外部依赖,这正是构建云原生平台的开发团队选择 NATS 的原因。

MQTT Streams 简介

MQTT Streams 随 EMQX 企业版 6.1 正式上线。流是带自定义名称的持久存储组件,会捕获所有匹配某个主题过滤器的 MQTT 消息,分为两种类型:

  1. 仅追加流:存储全量历史数据,支持任意时段数据回放。
  2. 最新值流:仅保留每个设备标识对应的最新一条消息,可视化仪表盘依靠该功能获取设备当前状态。

现有生产设备不受影响。任何发布到匹配主题的 MQTT 客户端都会向流中送入消息,而设备集群根本感知不到流的存在。

消费者通过使用 MQTT 5.0 订阅 $stream/<流名称>,并使用订阅属性 stream-offset 选择起始位置:最早、最新或某个时间戳。历史数据会先到达,再持续接收实时新增数据。数据回放就是一次 MQTT 订阅指令,无需额外操作。

EMQX 的另一个独立功能——消息队列,通过订阅 $queue/<队列名称> 进行消费:EMQX 会将每条消息精确地投递给订阅者中的某一个工作节点。

同一业务场景,两种实现方案

该演示项目通过一个 Compose 文件同时运行两套架构。两组设备集群使用各自消息中间件的原生协议:MQTT 传感器向 EMQX 发布消息,另一组设备则通过 NATS 协议向 NATS 发布。

两套技术栈完全对称——每侧各有一个消息中间件、一组传感器集群和四个消费者,两侧均不使用网关。这样可以排除转发层干扰,专注对比组件功能与业务适配度。

四个消费者在两侧分别验证持久流处理的各项需求:实时监听数据流、后启动消费端完整按序回放历史、仪表盘冷启动读取设备最新状态、双工作节点池分摊处理任务。两个系统均能实现这四项能力,核心差异体现在其他维度。

核心差异点

在基础消息能力上,二者表现接近:均可按顺序回放历史数据、实现工作队列负载均衡、存储每台传感器的最新值。

  • EMQX:依靠保留消息 + 最新值流实现;
  • NATS:依靠发布端写入键值存储桶,或按主题保留最新值的流实现。

二者的核心差异集中在五个关键的架构维度:

持久化消费者

NATS JetStream:在服务器端维护命名消费者的读取位点。如果某个消费者崩溃,只需重新连接即可从断开处精确恢复。对于不容许丢失或重复处理数据的长期运行链路而言,JetStream 的运维成本更低。

EMQX MQTT Streams:由流消费者自行记录读取位点,重连时手动指定起始点位恢复消费。

设备侧核心能力

物联网设备集群仅靠数据日志远远不够。EMQX 原生内置三项设备管理核心能力,而原生 NATS 协议不提供底层支持:

功能EMQX(原生 MQTT broke)原生 NATS(替代方案)
遗嘱消息设备突发离线时自动推送通知,不用额外开发超时检测逻辑需要基于连接事件,在业务层自行开发实现
保留消息仪表盘或备用设备完成订阅的瞬间,就能拿到设备最新状态,无需等待下一次上报需要手动维护键值存储桶,自行实现等效逻辑
单客户端持久会话为每台设备分配专属持久消息信箱,设备离线期间下发的指令,重连后会立刻推送必须在业务代码中自行开发逻辑实现

你可以用 NATS 在业务代码中自行开发上述三项功能。

在基础消息能力上二者持平(通配符、负载均衡订阅、消息头、v2.11 版本起支持单消息过期时间);NATS 的请求应答模式设计更完善,差距仅体现在物联网设备核心能力。

接入端协议

这通常是技术选型中最具决定性的因素:

  • MQTT 的主导地位:OT 和 IT 技术领域设备绝大多数采用 MQTT 协议,其中大量是第三方或固件固定的硬件,其协议你无法更改。如果你的设备必须使用 MQTT,EMQX 可直接在设备接入层内置持久流,无需中转。
  • NATS 生态:如果你的终端完全自主可控、可部署 NATS 客户端,MQTT 的生态优势便不复存在。此时选择就纯粹取决于功能特性,而 NATS 的功能覆盖范围更广。

开放标准 vs 单一实现

  • MQTT(EMQX):符合 OASIS 与 ISO/IEC 20922 标准,拥有多款可互操作的消息中间件与客户端(EMQX、HiveMQ、Mosquitto、各类云物联网服务)。设备层收益显著:设备使用通用标准协议,不受厂商锁定,更换消息中间件无需改动设备集群。
  • NATS:仅有 CNCF 官方的 nats-server。采用 Apache 2.0 开源协议,允许查看源码,但无其他兼容服务端可供迁移,协议迭代完全跟随单一项目规划。

公平地说,流处理特性在双方都是专有的——MQTT Streams 仅 EMQX 支持,JetStream 仅 NATS 支持;MQTT 带来的可迁移性体现在底层通信协议与设备接入层,而非流本身。

开源许可协议

  • NATS:在 Apache-2.0 下完全开源。
  • EMQX:自 v5.9 起采用统一版本,对单节点和非商业用途免费,但集群部署或商业生产环境需要许可证。

如果纯开源技术栈是你的架构硬性约束,许可协议会直接决定选型。

平台完整能力

除了数据流处理,两个产品本身都是一个完整的平台,选型需要结合整体架构考量:

  • NATS 扩展能力:键值存储、对象存储,原生支持请求-响应模式。
  • EMQX 扩展能力:内置 SQL 规则引擎,允许直连 Kafka 和各种数据库。

本文两个示例均按单设备有序存储数据,两个代码仓库中的回放消费者均验证了这一行为。

如何选型

选择 NATS JetStream

您的数据生产端、消费端均可以使用 NATS 客户端;或者您需要一个支持 Apache-2.0 协议,同时具备键值存储、对象存储和请求-响应能力的开源系统。JetStream 正是为此类场景设计,全链路基于 NATS 服务的架构成熟稳定。

选择 EMQX MQTT Streams

设备集群使用 MQTT 协议(绝大多数 OT 和 IT 场景),业务需要数据回放、实时状态读取、任务分发能力。流处理、设备接入、数据规则处理全部在同一套系统内完成,无需任何转换。

行业趋势

多年来,各类消息系统一直在相互借鉴彼此的核心能力:Kafka 通过共享消费组加入了队列式消费,RabbitMQ 增加了可回放的流,MQTT Broker 如今也在添加自己的持久日志和队列。产品标签能代表的能力边界越来越模糊,真正的区别在于是哪些客户端能原生接入,以及数据从哪里进入系统。

对于设备集群而言,数据入口通常就是 MQTT,那么流处理就应该放在设备所在的地方。

项目地址:github.com/emqx/emqx-streams-demo

通过 Docker 部署,15 分钟了解数据回放、实时状态、工作队列和 Broker 重启的全流程。

咨询 EMQ 技术专家
联系我们 →

文章作者

EMQX Team
EMQX Team

EMQX 团队专注于 EMQX Platform 的研发,不断打造高性能、可扩展的 MQTT 解决方案,助力物联网系统与 AI 技术融合,满足各行业不断演进的数字化需求。

订阅我们的博客