一、什么是MQTT?

MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

二、为什么MQTT是适用于物联网的最佳协议?

MQTT 所具有的适用于物联网特定需求的特点和功能,使其成为物联网领域最佳的协议之一。它的主要特点包括:

1、轻量级:

物联网设备通常在处理能力、内存和能耗方面受到限制。MQTT 开销低、报文小的特点使其非常适合这些设备,因为它消耗更少的资源,即使在有限的能力下也能实现高效的通信。

2、可靠:

物联网网络常常面临高延迟或连接不稳定的情况。MQTT 支持多种 QoS 等级、会话感知和持久连接,即使在困难的条件下也能保证消息的可靠传递,使其非常适合物联网应用。

3、安全通信:

安全对于物联网网络至关重要,因为其经常涉及敏感数据的传输。为确保数据在传输过程中的机密性,MQTT 提供传输层安全(TLS)和安全套接层(SSL)加密功能。此外,MQTT 还通过用户名/密码凭证或客户端证书提供身份验证和授权机制,以保护网络及其资源的访问。

4、双向通信:

MQTT 的发布-订阅模式为设备之间提供了无缝的双向通信方式。客户端既可以向主题发布消息,也可以订阅接收特定主题上的消息,从而实现了物联网生态系统中的高效数据交换,而无需直接将设备耦合在一起。这种模式也简化了新设备的集成,同时保证了系统易于扩展。

5、连续、有状态的会话:

MQTT 提供了客户端与 Broker 之间保持有状态会话的能力,这使得系统即使在断开连接后也能记住订阅和未传递的消息。此外,客户端还可以在建立连接时指定一个保活间隔,这会促使 Broker 定期检查连接状态。如果连接中断,Broker 会储存未传递的消息(根据 QoS 级别确定),并在客户端重新连接时尝试传递它们。这个特性保证了通信的可靠性,降低了因间断性连接而导致数据丢失的风险。

6、大规模物联网设备支持:

物联网系统往往涉及大量设备,需要一种能够处理大规模部署的协议。MQTT 的轻量级特性、低带宽消耗和对资源的高效利用使其成为大规模物联网应用的理想选择。通过采用发布-订阅模式,MQTT 实现了发送者和接收者的解耦,从而有效地减少了网络流量和资源使用。此外,协议对不同 QoS 等级的支持使得消息传递可以根据需求进行定制,确保在各种场景下获得最佳的性能表现。

7、语言支持:

物联网系统包含使用各种编程语言开发的设备和应用。MQTT 具有广泛的语言支持,使其能够轻松与多个平台和技术进行集成,从而实现了物联网生态系统中的无缝通信和互操作性。您可以阅读我们的 MQTT 客户端编程系列文章,学习如何在 PHP、Node.js、Python、Golang、Node.js 等编程语言中使用 MQTT。

三、MQTT的工作原理

要了解 MQTT 的工作原理,首先需要掌握以下几个概念:MQTT 客户端、MQTT Broker、发布-订阅模式、主题、QoS。

1、MQTT 客户端

任何运行 MQTT 客户端库的应用或设备都是 MQTT 客户端。例如,使用 MQTT 的即时通讯应用是客户端,使用 MQTT 上报数据的各种传感器是客户端,各种 MQTT 测试工具也是客户端。

2、MQTT Broker

MQTT Broker 是负责处理客户端请求的关键组件,包括建立连接、断开连接、订阅和取消订阅等操作,同时还负责消息的转发。一个高效强大的 MQTT Broker 能够轻松应对海量连接和百万级消息吞吐量,从而帮助物联网服务提供商专注于业务发展,快速构建可靠的 MQTT 应用。

关于 MQTT Broker 的更多详情,请参阅文章 2023 年最全面的 MQTT Broker 比较指南

3、发布-订阅模式

发布-订阅模式与客户端-服务器模式的不同之处在于,它将发送消息的客户端(发布者)和接收消息的客户端(订阅者)进行了解耦。发布者和订阅者之间无需建立直接连接,而是通过 MQTT Broker 来负责消息的路由和分发。

下图展示了 MQTT 发布/订阅过程。温度传感器作为客户端连接到 MQTT Broker,并通过发布操作将温度数据发布到一个特定主题(例如 Temperature)。MQTT Broker 接收到该消息后会负责将其转发给订阅了相应主题(Temperature)的订阅者客户端。 WechatIMG8.jpg

四、EMQX相关信息

1、emqx官网地址:

https://www.emqx.com/zh

2、emqx开源软件服务端下载地址:

https://www.emqx.com/zh/downloads-and-install/broker?os=RHEL 注:不管是使用的yum还是package包都要对应里边的系统版本去下载使用。我这里测试使用的是centos8对应的package包 WechatIMG6.jpg

3、mqx开源软件客户端下载地址:

https://mqttx.app/zh/downloads

五、启动emqx

1、下载对应emqx的安装包

wget https://www.emqx.com/zh/downloads/broker/5.8.0/emqx-5.8.0-el8-amd64.rpm

2、安装emqx

yum install -y emqx-5.8.0-el8-amd64.rpm

3、启动emqx并设置开机自启

systemctl start emqx systemctl enable emqx

4、查看emqx服务

netstat -antupl | grep emqx 注:emqx默认的服务通信端口是1883,默认的服务web端口是18083。如果内网或者局域网本地访问以上方式已经满足。接下来是为了通过公网域名来访问做的配置,局域网内的需求不需要。

六、安装nginx服务器

这块不多说了哈 自行百度遍地都是 各种方式安装都行,需要提一嘴的是首先nginx版本要在1.9以上,然后如果是源码编译安装需要加一个模块--with-stream,如果需要开启ssl也需要在加上--with-stream_ssl_module这个模块,有同学就会满脑瓜子问号:

1、为啥要求nginx1.9以上?

2、为啥需要--with-stream模块?

3、为啥需要--with-stream_ssl_module这个模块?

注:解释一下首先emqx这个服务通信使用的是tcp并非http或者https,所以呢就需要我们在做nginx转发的时候应用tcp转发模块也就是--with-stream,但是呢nginx在1.9版本之前没有转发tcp或者udp的模块支持功能,1.9版本以后才支持使用这个模块,至于--with-stream_ssl_module这个模块不是必须的,如果要开启ssl就使用,不开启就不使用即可。

七、配置nginx的配置文件

1、配置nginx的tcp转发到emqx服务(使用域名)

cat /etc/nginx/nginx.conf

stream {
    upstream mqtt_backend {
        server IP地址:1883; # 假设MQTT代理运行在本地的1883端口
    }

    server {
        listen 18830; # MQTT标准端口
        proxy_pass mqtt_backend;
        proxy_connect_timeout 150s;
        proxy_timeout 150s;
        proxy_buffer_size 3M;
        tcp_nodelay on;
    }
}

WechatIMG10.jpg

2、配置emqx的web(使用域名)

cat web.conf

server {
    server_name ;
    listen 80;
    location / {
        proxy_pass http://127.0.0.1:18083;
    }
}

WechatIMG12.jpg 注:防止有小伙伴不知道这个端口号,这里解释一下,1883端口不用说了哈是emqx的通信端口,18830是我给他随便设置的一个对外暴露端口,也就是说客户端要连接服务端需要添加域名+18830端口号,你也可以自行更改。再强调一下18083端口是默认的emqx服务web端口所以,将nginx的默认80端口web转发到本地的emqx服务web端口,这样就实现了访问域名即可直接访问到emqx服务的web页面。

3、域名访问emqx的web

WechatIMG14.jpg 注:以上页面证明域名访问emqx服务web完成,但是有没有发现web加载特别慢,这里解释一下:因为emqx服务的web有几个比较大的页面,所以呢?我们需要对默认的nginx做些优化,如下:

sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    gzip on;

WechatIMG18.jpg 注:这里为了测试所以放到了公网,为了安全建议后台还是在内网访问。

八、开启阿里云的ecs安全组

1、找到ecs服务器

2、选择安全组

3、选择“入方向”

4、手动添加

WechatIMG20.jpg 注:这不操作是为了nginx域名tcp转发到emqx的1883服务端口,因为使用的是18830对外暴露,所以需要给他开通安全组的端口限制。