第一章:EMQX简介

1,061 阅读9分钟

第一章: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_submosquitto_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 通过桥接插件将消息分发到大数据平台,助力企业实现实时数据分析与决策。