第一章:EMQX简介
1、什么是EMQX
EMQX 是一款开源、高性能的分布式 MQTT 消息中间件,专为物联网(IoT)、实时数据传输和消息分发场景设计。EMQX 的主要职责是帮助设备之间快速、稳定地交换信息,让它们能够实时通信。它广泛应用于智能家居、工业物联网、车联网等需要高并发连接和低延迟消息传递的领域。
1.1、核心功能与特性
- 支持海量设备连接
- EMQX 利用 Erlang/OTP 的高并发特性,支持单机百万级设备连接,是物联网场景的理想选择。
- 分布式架构
- EMQX 提供强大的分布式集群能力,支持动态扩展节点,具备高可用性和容错能力。
- 支持多种协议
- EMQX 以 MQTT 协议为核心,同时支持 MQTT-SN、CoAP、HTTP、WebSocket 等协议,满足不同设备与系统的通信需求。
- 插件化设计
- 用户可通过丰富的插件扩展功能,例如认证授权、消息持久化、数据桥接等,灵活适配复杂场景。
- 开箱即用的易用性
- EMQX 提供简单易懂的安装和配置流程,即便是新手开发者也能快速上手。
1.2、工作原理
EMQX 基于 发布/订阅(Pub/Sub)模型,客户端通过订阅特定的主题(Topic)来接收消息,其他客户端通过发布消息到相应主题来共享信息。作为消息中间件,EMQX 负责处理消息的传递、存储和安全。
2、什么是MQTT协议
MQTT(Message Queuing Telemetry Transport) 是一种轻量级的、基于 发布/订阅模型 的消息通信协议,设计之初便考虑到低带宽和高延迟网络环境,是物联网领域的首选通信协议。
2.1、MQTT协议的特点
- 轻量级与高效
- 协议设计简单,传输数据开销小,适合带宽有限或不稳定的网络(如移动网络、卫星通信等)。
- 发布/订阅模型
- 基于主题(Topic)实现的消息分发,客户端可以发布消息到某主题,也可以订阅主题来接收消息,避免了设备直接点对点通信的复杂性。
- 服务质量等级(QoS)
- 提供三种消息服务质量等级:
- QoS 0:最多一次传递,可能丢失。
- QoS 1:至少一次传递,可能重复。
- QoS 2:确保消息只传递一次。
- 提供三种消息服务质量等级:
- 持久化会话
- 客户端断开连接后,服务器会保存其订阅信息,待客户端重新连接时恢复会话。
- 安全性
- 支持 SSL/TLS 加密,保障通信的安全性。
- 跨平台与低成本
- MQTT 适用于各种设备和操作系统,从微型传感器到云服务器,都能高效使用。
2.2、基本的发布/订阅模型
Python使用paho-mqtt库进行 MQTT 发布/订阅操作
- 安装paho-mqtt库:
前往官网直接根据pip指令下载。 - 发布端代码示例:
import paho.mqtt.client as mqtt
import random
import time
# 连接成功回调
class Mqtt_Publisher:
'''
mqtt消息通讯接口
'''
def __init__(self,central_ip='10.8.20.224',port=1883,node_name='bci_',anonymous=True,timeout=60):
'''
:param central_ip: Broker的地址
:param port: 端口号
:param timeout: 连接延时
:param node_name: 节点名称
:param anonymous: 是否同时允许多个节点
'''
self.broker_ip=central_ip
self.broker_port=port
self.timeout=timeout
self.connected=False
self.node_name=node_name
if anonymous:
self.node_name=self.node_name+str(random.randint(100000,999999))
self.Start()
def Start(self):
'''
开启publisher
:return:
'''
self.client = mqtt.Client(self.node_name) #创建客户端
self.client.on_connect = self.on_connect # 指定回调函数
self.client.connect(self.broker_ip, self.broker_port, self.timeout) #开始连接
self.client.loop_start() #开启一个独立的循环通讯线程。
def Publish(self,topic,payload,qos=0,retain=False):
'''
发送一个mqtt消息
:param topic: 消息名称,string类型
:param payload: 消息内容,string类型
:param qos: 消息等级
:retain: 状态机消息
:return:
'''
if self.connected:
return self.client.publish(topic, payload=payload, qos=qos, retain=retain)
else:
raise Exception("mqtt server not connected! you may use .Start() function to connect to server firstly.")
'''
回调函数
'''
def on_connect(self,client, userdata, flags, rc):
'''
连接到broker的回调函数
'''
if rc==0:
self.connected=True
else:
raise Exception("Failed to connect mqtt server.")
if __name__=='__main__':
p=Mqtt_Publisher()
while not p.connected:
pass
while True:
p.Publish('test','this is a test message')
p.Publish('test_2','this is test 2')
time.sleep(1)
- 订阅端代码示例:
import paho.mqtt.client as mqtt
import threading
import random
import time
# 连接成功回调
class Mqtt_Subscriber:
'''
mqtt消息通讯接口
'''
def __init__(self,central_ip='10.8.20.224',port=1883,
topic_name='test_2',callback_func=None,
node_name='bci_',anonymous=True,timeout=60):
'''
:param central_ip: Broker的地址
:param port: 端口号
:param topic_name: 接收的消息名称
:param callback_func: 指定回调函数
:param timeout: 连接延时
:param node_name: 节点名称
:param anonymous: 是否同时允许多个节点
'''
self.topic=topic_name
self.callback=callback_func
self.broker_ip=central_ip
self.broker_port=port
self.timeout=timeout
self.connected=False
self.node_name=node_name
if anonymous:
self.node_name=self.node_name+str(random.randint(100000,999999))
self.Start()
def Start(self):
'''
开启publisher
:return:
'''
self.client = mqtt.Client(self.node_name) #创建客户端
self.client.on_connect = self.on_connect # 指定回调函数
self.client.on_message=self.default_on_message
self.client.connect(self.broker_ip, self.broker_port, self.timeout) #开始连接
self.client.subscribe(self.topic)
self.client.loop_start() #开启一个独立的循环通讯线程。
'''
回调函数
'''
def default_on_message(self,client, userdata, msg):
'''
默认回调函数
'''
print(msg.payload.decode('utf-8'))
def on_connect(self,client, userdata, flags, rc):
'''
连接到broker的回调函数
'''
if rc==0:
self.connected=True
else:
raise Exception("Failed to connect mqtt server.")
if __name__=='__main__':
p=Mqtt_Subscriber()
while not p.connected:
pass
while True:
time.sleep(1)
Ubuntu系统使用Mosquitto进行 MQTT 发布/订阅操作
- 安装 Mosquitto
更新系统包 : 首先,更新系统的包管理器,以确保你安装的是最新版本的软件:
sudo apt update
安装 Mosquitto : 使用以下命令安装 Mosquitto:
sudo apt install mosquitto mosquitto-clients
mosquitto:安装 Mosquitto MQTT Broker。
mosquitto-clients:安装 MQTT 客户端工具,可以用来进行发布和订阅操作。
- 启动 Mosquitto 服务
安装完成后,Mosquitto 会自动启动。你可以使用以下命令检查 Mosquitto 服务是否正在运行:
sudo systemctl status mosquitto
如果服务未启动,可以使用以下命令启动它:
sudo systemctl start mosquitto
- 配置 Mosquitto(可选)
Mosquitto 默认配置已经可以用于测试。
如果你需要修改配置文件,编辑 /etc/mosquitto/mosquitto.conf 文件:
sudo nano /etc/mosquitto/mosquitto.conf
在这里你可以配置端口、身份验证、安全性等设置。修改完后,重新启动服务以使设置生效:
sudo systemctl restart mosquitto
-
使用 Mosquitto 客户端进行 MQTT 订阅
在终端中,使用
mosquitto_sub命令来订阅一个主题。例如,订阅test/topic主题:
mosquitto_sub -h localhost -t "test/topic"
-h localhost:指定 Mosquitto 服务器的主机地址。这里使用本地服务器(localhost)。
-t "test/topic":指定要订阅的主题。
此命令将保持运行并等待消息发布到 test/topic 主题。如果有其他客户端发布消息,该订阅者将会接收到消息。
- 使用 Mosquitto 客户端进行 MQTT 发布
在另一个终端中,使用 mosquitto_pub 命令发布消息到 test/topic 主题:
mosquitto_pub -h localhost -t "test/topic" -m "Hello, MQTT!"
-h localhost:指定 Mosquitto 服务器的主机地址。
-t "test/topic":指定要发布的主题。
-m "Hello, MQTT!":指定要发布的消息内容。
此命令会将 "Hello, MQTT!" 发送到 test/topic 主题。
- 测试发布/订阅
在一个终端中运行订阅命令:
mosquitto_sub -h localhost -t "test/topic"
该命令会一直等待消息发布。
在另一个终端中运行发布命令:
mosquitto_pub -h localhost -t "test/topic" -m "Hello, MQTT!"
订阅者终端应该立即接收到消息 "Hello, MQTT!"。
-
使用
mosquitto_sub和mosquitto_pub的高级功能- 设置消息的 QoS(服务质量)
在发布和订阅时,你可以设置不同的 QoS(服务质量)级别:
QoS 0:消息最多传递一次,可能丢失。
QoS 1:消息至少传递一次,可能重复。
QoS 2:消息确保仅传递一次。
订阅时设置 QoS:
mosquitto_sub -h localhost -t "test/topic" -q 1
发布时设置 QoS:
mosquitto_pub -h localhost -t "test/topic" -m "Hello, MQTT!" -q 1
- 使用遗嘱消息
遗嘱消息(LWT,Last Will and Testament)是指在客户端非正常断开时,服务器会发布一条消息。设置遗嘱消息时,需要指定主题和消息内容。
发布时设置遗嘱消息:
mosquitto_pub -h localhost -t "test/topic" -m "Goodbye, MQTT!" -l -q 1
设置消息保留(Retain)
保留消息(Retain)是一种特殊类型的消息,当该消息被发布时,Mosquitto 会保存这条消息,并且之后的新订阅者可以立即接收到该消息,而不必等到下一条消息的发布。
发布保留消息:
mosquitto_pub -h localhost -t "test/topic" -m "This is a retained message" -r
订阅时接收保留消息:
mosquitto_sub -h localhost -t "test/topic"
在订阅该主题时,你将立即接收到之前发布的保留消息。
- 测试和调试
你可以通过查看 Mosquitto 的日志来帮助调试问题。
日志通常位于 /var/log/mosquitto/mosquitto.log 文件中,或者根据你的配置文件不同,日志位置可能会有所不同。
查看日志文件:
tail -f /var/log/mosquitto/mosquitto.log
- 配置 Mosquitto 开机启动(可选)
如果你希望 Mosquitto 在系统启动时自动启动,可以使用以下命令启用它:
sudo systemctl enable mosquitto
2.3、MQTT协议的应用场景
- 智能家居:通过 MQTT 实现家电设备的远程控制和状态同步。
- 工业物联网:传感器数据上传到云平台,实现实时监控与数据分析。
- 车联网:车辆位置、状态数据的实时上传,辅助导航和车队管理。
3、为什么选择EMQX
选择 EMQX 的原因可以从其技术优势、生态支持和实际应用场景三个角度分析:
3.1、技术优势
- 卓越的性能表现:
- EMQX 利用 Erlang/OTP 的并发优势,单机即可支持百万级设备连接,且消息传递延迟低至毫秒级。
- 灵活的架构:
- 支持横向扩展,用户可以通过添加节点轻松扩展系统容量;同时具备高可用性,避免单点故障。
- 支持多种协议:
- 除了 MQTT,EMQX 还支持 HTTP、WebSocket、MQTT-SN 等协议,能轻松适配不同设备和系统的需求。
- 丰富的功能插件:
- 提供多种开箱即用的插件,支持认证授权、日志存储、数据桥接到第三方系统(如 Kafka、MySQL 等)。
- 可视化管理工具:
- 提供基于 Web 的管理界面(Dashboard),用户可以方便地监控和管理系统运行状态。
3.2、生态支持
- 社区支持:
- EMQX 拥有活跃的开源社区,提供丰富的技术资源和插件,开发者可以快速获取帮助。
- 多种集成能力:
- 能与主流数据平台(如 Kafka、Elasticsearch、MySQL)无缝集成,用于数据存储与分析。
3.3、实际应用场景
- 物联网(IoT)应用:
- 智能家居、智能城市、工业自动化中,EMQX 提供设备间的稳定通信桥梁。
- 实时消息推送:
- EMQX 可作为即时通信平台的核心,保障高效可靠的消息推送。
- 数据分析与处理:
- EMQX 通过桥接插件将消息分发到大数据平台,助力企业实现实时数据分析与决策。