RabbitMQ对接MQTT消息发布指南

好的,完全没问题。使用 RabbitMQ 向 MQTT 主题发布消息,核心在于启用并配置 RabbitMQ 的 MQTT 插件。这个插件使得 RabbitMQ 能够"听懂" MQTT 协议,并作为一座桥梁,在 AMQP(RabbitMQ 的默认协议)世界和 MQTT 世界之间路由消息。

整个过程的架构图可以理解为:

复制代码
[AMQP Producer] --> (RabbitMQ Broker /w MQTT Plugin) --> [MQTT Subscriber]
      |                      |
  (amqp://)              (mqtt://)

下面是详细的步骤和配置说明。

核心原理

RabbitMQ 的 MQTT 插件会创建一个 MQTT 监听器(默认端口 1883)。当它收到消息后,会根据特定的规则将 MQTT 的 topic 转换(映射)为 RabbitMQ 的 exchangerouting key,从而让消息进入 RabbitMQ 的消息流转系统。反之,从 RabbitMQ 发往特定 Exchange 的消息也会被插件转换为 MQTT 消息发送出去。

步骤一:启用 MQTT 插件

首先,确保你的 RabbitMQ 服务器上已经安装并启用了 MQTT 插件。

bash 复制代码
# 进入 RabbitMQ 的 sbin 目录(你的安装路径可能不同)
cd /usr/local/opt/rabbitmq/sbin

# 启用插件
rabbitmq-plugins enable rabbitmq_mqtt

# 重启 RabbitMQ 服务使插件生效
rabbitmq-service stop
rabbitmq-service start
# 或者使用 systemctl (Linux)
# systemctl restart rabbitmq-server

启用成功后,你可以在 RabbitMQ 的管理控制台(通常位于 http://your-server-ip:15672)的 Overview -> Listeners 中看到多了一个监听在 1883 端口的协议为 MQTT 的监听器。

步骤二:理解默认的 Topic-Exchange 映射规则

这是最关键的一步。插件默认使用以下规则进行映射:

  • Exchange : MQTT 主题会被映射到一个名为 amq.topicTopic 类型 的预定义 Exchange。
  • Routing Key: MQTT 的 Topic 名称直接作为 RabbitMQ 的 Routing Key。

例如:

一个 MQTT 客户端向主题 my/home/living-room/temperature 发布消息。

  • RabbitMQ MQTT 插件会接收到这个消息。
  • 插件会将这个消息发布 到 RabbitMQ 内置的 amq.topic 这个 Exchange 上。
  • 使用的 Routing Key 就是 my.home.living-room.temperature (注意:插件默认会将 MQTT topic 中的 / 替换为 .,但这个行为是可配置的)。

重要提示amq.topic 是一个内置的 Topic Exchange,它默认就存在,所以你不需要手动创建它。

步骤三:从 RabbitMQ 发送消息到 MQTT 主题

现在,你的目标是从一个 AMQP 客户端(比如用 Python、Java 等编写的生产者)发送消息,让一个 MQTT 订阅者能收到。

根据上面的映射规则,你需要做的是:amq.topic 这个 Exchange 发送一条消息,并且其 Routing Key 等于目标 MQTT 主题(通常将 / 替换为 .

示例:使用 Python (pika库)

假设你想让 MQTT 客户端订阅 my/home/living-room/temperature 主题并收到消息。

python 复制代码
import pika
import json

# 连接到 RabbitMQ Server
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 消息内容
message = {
    "device_id": "sensor-123",
    "value": 22.5,
    "unit": "celsius"
}

# 关键步骤:
# 1. 发布到 'amq.topic' exchange
# 2. routing_key 设置为 MQTT Topic,并将 '/' 替换为 '.' 
#    (即 'my.home.living-room.temperature')
routing_key_for_rabbitmq = "my.home.living-room.temperature".replace('/', '.')

channel.basic_publish(
    exchange='amq.topic',         # 使用固定的 amq.topic exchange
    routing_key=routing_key_for_rabbitmq,
    body=json.dumps(message)
)

print(f" [x] Sent to RabbitMQ (routing_key: {routing_key_for_rabbitmq}): {message}")
connection.close()

步骤四:测试验证

使用一个 MQTT 客户端订阅主题,来验证消息是否成功从 RabbitMQ 流转过来。

例如,使用 mosquitto_sub 命令行工具:

bash 复制代码
mosquitto_sub -h your-rabbitmq-server-ip -t "my/home/living-room/temperature" -v
  • -h: 你的 RabbitMQ 服务器地址
  • -t: 要订阅的 MQTT 主题
  • -v: 打印出主题和消息内容

运行这个订阅命令后,再去执行上面的 Python 脚本。如果一切配置正确,你将在 mosquitto_sub 终端中看到发送的消息。

复制代码
my/home/living-room/temperature {"device_id": "sensor-123", "value": 22.5, "unit": "celsius"}

高级配置(可选)

默认的映射规则可能不满足所有场景。你可以在 RabbitMQ 的配置文件 (rabbitmq.conf) 中自定义 MQTT 插件的行为。

示例配置:

conf 复制代码
# 将 MQTT 主题前缀为 "mqtt." 的消息路由到另一个 exchange
mqtt.exchange = my_mqtt_exchange

# 更精细的权限和 topic 配置
mqtt.default_user = guest
mqtt.default_pass = guest
mqtt.allow_anonymous = true
mqtt.vhost = /
mqtt.topic_namespace = mqtt_

修改配置后需要重启 RabbitMQ 服务。详细的配置选项请参考官方文档:RabbitMQ MQTT Plugin Configuration

总结

  1. 启用插件rabbitmq-plugins enable rabbitmq_mqtt
  2. 理解映射 :MQTT Topic a/b/c 默认映射到 RabbitMQ 的 amq.topic exchange 和 a.b.c routing key。
  3. 发送消息 :让你的 AMQP 生产者向 amq.topic exchange 发送消息,routing key 使用转换后的 MQTT topic(/ -> .)。
  4. 接收消息 :任何订阅了原始 MQTT topic(如 a/b/c)的 MQTT 客户端都会收到这条消息。

通过这种方式,RabbitMQ 就成功地成为了一个支持 MQTT 协议的强大消息代理,轻松实现了两种协议之间的互联互通。

相关推荐
u0104058363 小时前
霸王餐返利app的分布式架构设计:基于事件驱动的订单处理系统
分布式
JAVA学习通3 小时前
【RabbitMQ】高级特性:持久性·发送方确认·重试机制·TTL·死信队列·延迟队列·事务·消息分发
分布式·rabbitmq
海阔天空在前走3 小时前
MQ防止重复消费的四种方法
分布式·rabbitmq
AD钙奶-lalala4 小时前
RabbitMQ在Mac OS上的安装和启动
分布式·rabbitmq
七夜zippoe10 小时前
事务方案选型全景图:金融与电商场景的实战差异与落地指南
java·分布式·事务
葵野寺13 小时前
【RelayMQ】基于 Java 实现轻量级消息队列(七)
java·开发语言·网络·rabbitmq·java-rabbitmq
在未来等你14 小时前
Kafka面试精讲 Day 12:副本同步与数据一致性
大数据·分布式·面试·kafka·消息队列
蒋士峰DBA修行之路15 小时前
实验九 合理定义分布列实现性能优化-分布式聚集
分布式
echoyu.16 小时前
消息队列-kafka完结
java·分布式·kafka