MQTT(消息队列)简介
MQTT(MQ Telemetry Transport)是IBM开发的一种网络应用层的协议,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。
常用的有eclipse paho、activeMQ、阿里MQTT和其他的实现。
使用场景
- 不可靠、网络带宽小的网络
- 运行的设备CPU、内存非常有限
特点
- 基于发布/订阅模型的协议
- 他是二进制协议(协议头只有2个字节),二进制的特点就是紧凑、占用空间小
- 提供了三种消息可能性保障(Qos):
- 0:最多一次
- 1:最少一次
- 2:只有一次
以Qos=2(保证消息可达)为例介绍,客户端一条消息发送到服务端需要交互4次:
关键字术语
- HOST:搭载MQTT的服务器地址
- TOPIC:消息主题,可以被客户端订阅,实现对应消息的收发
- clientId:客户端ID,用于服务器对不同客户端的识别
- subscribe/unsubscribe:客户端对消息主题的订阅和取消订阅
- Qos:消息的服务质量,当网络过载或拥塞时,QoS 能确保重要业务量不受延迟或丢弃
- Callback:当客户端收到消息后对消息的处理(回调)
- KeepAliveInterval:客户端与服务器之间的连接是通过发送心跳包来保持存活
自建服务器
EMQ
下载emq开源软件
# 下载程序包
wget https://www.emqx.io/downloads/broker/v4.0.5/emqx-centos7-v4.0.5.zip
# 解压
unzip emqx-centos7-v4.0.5.zip
运行程序
cd emqx
# 打开程序命令行终端
./bin/emqx console
此时服务已经开启,CTRL+ C 关闭终端。也可以使用守护进程模式启动
./bin/emqttd start
启动错误日志将输出在 log/ 目录。EMQ 消息服务器进程状态查询:
./bin/emqttd_ctl status
使用ECS服务器开放端口
需要开放以下端口:
或者使用nginx代理。
授权方式
使用mysql、pgsql等数据库校验方式。请参考:mysql认证
Apache-apollo
Apollo是ActiveMQ的子工程,是ActiveMQ的下一代消息代理。
Apollo 是一个更快、更可靠、更容易维护的消息代理,它是由最初的ActiveMQ的基础构建的。它使用一个完全不同的线程和消息调度架构来实现这一点。与ActiveMQ一样,apollo 是一个多协议代理,支持STOMP、AMQP、MQTT、Openwire、SSL和WebSockets。
MQTT 通配符
⚠️:MQTT允许使用通配符订阅主题,但是并不允许使用通配符广播。 原文 Appendix A - Topic wildcards
一个订阅可能包含特殊字符,允许你一次定义多个主题。
主题层次分隔符被用来在主题中引入层次。多层的通配符和单层通配符可以被使用,但他们不能被使用来做发布者的消息。
主题层级分隔符/
/
被用来分割主题树的每一层,并给主题空间提供分等级的结构。当两个通配符在一个主题中出现的时候,主题层次分隔符的使用是很重要的。
多层通配符#
#
是一个匹配主题中任意层次数的通配符。比如说,如果你订阅了finance/stock/ibm/#
,你就可以接收到以下这些主题的消息。
- finance/stock/ibm
- finance/stock/ibm/closingprice
- finance/stock/ibm/currentprice
多层通配符有可以表示大于等于0的层次。因此,finance/#
也可以匹配到单独的finance
,在这种情况下#代表0层。在这种语境下主题层次分隔符/
就没有意义了。因为没有可以分的层次。
多层通配符只可以确定当前层或者下一层。因此,#
和finance/#
都是有效的,但是finance#
不是有效的。多层通配符一定要是主题树的最后一个字符。比如说,finance/#
是有效的,但是finance/#/closingprice
是无效的。
单层通配符+
+
只匹配主题的一层。比如说,finance/stock/+
匹配finance/stock/ibm
和finance/stock/xyz
,但是不匹配finance/stock/ibm/closingprice
。另外,因为单层通配符只匹配1层,finance/+
不匹配finance
。
单层通配符可以被用于主题树的任意层级,连带多层通配符。它必须被用在主题层级分隔符/
的右边,除非它是指定自己。因此,+
和finance/+
都是有效的,但是finance+
无效。单层通配符可以用在主题树的末端,也可以用在中间。比如说,finance/+
和finance/+/ibm
都是有效的。
主题语法和用法
当你建立一个应用,设计主题树的时候应该考虑以下的主题名字的语法和语义:
- 主题至少有一个字符长。
- 主题名字是大小写敏感的。比如说,Accounts和accounts是两个不同的主题。
- 主题名字可以包含空格。比如,Accounts payable是一个有效的主题。
- 以
/
开头会产生一个不同的主题。比如说,/finnace
与finance
不同。/finance
匹配"+/+"
和/+
,但不匹配+
- 不要在任何主题中包含null(Unicode \x0000)字符。
以下的原则应用于主题树的建造和内容
- 在主题树中,长度被限制于64k内但是在这以内没有限制层级的数目 。
- 可以有任意数目的根节点,也就是说,可以有任意数目的主题树。
疑难杂症
订阅即收到固定推送
在某次推送时选择了retain模式,以后只要是订阅了该主题,就会按照retain模式下最后一次发送的内容进行推送。