RocketMQ MQTT 概览
传统消息队列MQ主要应用于服务端之间的消息通信,如电商领域的交易、支付、物流等消息。然而,随着物联网(IoT)及移动互联网的发展,来自IoT设备和手机APP端的消息呈爆炸式增长,规模远远超出了传统的服务端消息。这类终端设备消息需要更高效、更统一的消息系统来管理。
通过建立统一的消息系统,可实现多场景计算(如流式计算和事件驱动计算),并实现多场景(如IoT设备、手机APP和服务端)消息的统一接入与管理。数据统一存储于同一系统,能有效降低存储成本,避免跨系统数据同步带来的数据一致性问题。
因此,我们引入了 RocketMQ-MQTT 扩展项目,以实现 RocketMQ 统一接入 IoT 设备与服务端消息,提供一体化消息存储与互通能力。
MQTT协议简介
在IoT终端场景,目前业界广泛使用的是MQTT协议。MQTT 起源于物联网IoT场景,是一种基于发布/订阅(Pub/Sub)模式的轻量级消息传输协议,专为低带宽和网络不稳定的物联网环境设计。它最初由IBM开发,现由OASIS联盟作为开放标准维护。MQTT 广泛应用于物联网、智能硬件、车联网、智慧城市、远程医疗、电力、石油与能源等多个领域。
MQTT 的核心通信模型也是 Pub/Sub,与 RocketMQ 比较类似,但在订阅方式上更为灵活,支持多级 Topic 订阅(如 /t/t1/t2)和通配符订阅(如 /t/t1/+)。通过 MQTT,我们可以轻松实现消息的广播、组播及单播。
RocketMQ MQTT 架构设计
RocketMQ MQTT 架构的目标是实现消息存储与分发的统一管理,并在不侵入 RocketMQ Broker 核心逻辑的前提下实现多协议接入。为此,我们设计了两大核心模型:队列存储模型和推拉模型。
队列存储模型
我们设计了一种多维度分发的Topic队列模型,如上图所示,消息可以来自各个接入场景(如服务端的MQ/AMQP、客户端的MQTT),但只会写一份存到commitlog里面,然后分发出多个需求场景的队列索引(ConsumerQueue),如服务端场景(MQ/AMQP)可以按照一级Topic队列进行传统的服务端消费,客户端MQTT场景可以按照MQTT多级Topic以及通配符订阅进行消费消息。
这样的一个队列模型就可以同时支持服务端和终端场景的接入和消息收发,达到一体化的目标。
推拉模型
上图展示的是一个推拉模型,图中的P节点是一个协议网关或broker插件,终端设备通过MQTT协议连到这个网关节点。消息可以来自多种场景(MQ/AMQP/MQTT)发送过来,存到Topic队列后会有一个notify逻辑模块来实时感知这个新消息到达,然后会生成消息事件(就是消息的Topic名称),将该事件推送至网关节点,网关节点根据终端订阅的主题匹配消息事件,并触发 pull 请求至存储层,最终将消息推送至订阅终端。
架构概览
我们的目标是期望基于RocketMQ实现一体化且自闭环,但不希望Broker被侵入更多场景逻辑,我们抽象了一个协议计算层,这个计算层可以是一个网关,也可以是一个broker插件。Broker专注解决Queue的事情以及为了满足上面的计算需求做一些Queue存储的适配或改造。协议计算层负责协议接入,并且要可插拔部署。