零:说在前面
最近在研究物联网相关内容,需要接收 Modbus 协议的数据。上游数据源提出由对方整合数据后使用 MQTT 协议将数据发送过来,因此需要了解一下什么是 MQTT。
首先,它是一个类似 kafka 的“发布/订阅”模式的消息框架,但是性能、并发量、持久化、水平扩展 等方面远不如 kafka ,默认它不开启持久化,也无法水平扩展。它更多用于物联网应用场景下的、少量数据的消息传输。
其次,它的服务端和客户端之间可以保持长连接,客户端在每个心跳周期向服务端发送两节子的 PINGREQ 心跳报文,服务端收到后回复两字节的PINGRESP 报文,超过1.5个心跳周期没有报文,则服务端断开与客户端连接。
前置信息暂时说到这里,下面开始搭建环境
一、安装部署
1.1、在 Centos7 服务器上查找是否存在 mosquitto 软件包
[root@mysql1 redis-6.2.14]# yum list all | grep mosquitto
正确情况下应该看到如下图所示的两行内容
1.2、安装 EPEL 包
即使看不到如上图那两行内容也没事,只需将 EPEL 软件包添加到系统中即可。(PS:EPEL 的作用旨在为RHEL(Red Hat Enterprise Linux)及其衍生发行版如CentOS和Scientific Linux提供高质量的额外软件包。),如下所示
## 安装epel
[root@mysql1 redis-6.2.14]# yum install epel-release
## yum 重建缓存
[root@mysql1 redis-6.2.14]# yum clean all
[root@mysql1 redis-6.2.14]# yum update
[root@mysql1 redis-6.2.14]# yum makecache
1.3、安装
上面的命令执行成功后再次查找 mosquitto 软件包,应该就有结果了。然后安装mosquitto
[root@mysql1 redis-6.2.14]# yum install mosquitto
执行命令查看 mosquitto 安装结果,若看到如下图所示版本号,说明安装成功
[root@mysql1 redis-6.2.14]# yum list installed | grep mosquitto
二、测试通信
用一种ssh 工具(XShell 、SecureCRT 等)打开多个页签,第一个页签启动 mosquitto ,直接执行“mosquitto”命令即可,然后会看到如下图所示结果,说明 mosquitto 服务已启动
打开第二个页签,以接受者角色连接 mosquitto 服务,命令如下
## mosquitto_sub 以接收者角色连接, -t 代表主题名称
[root@mysql1 ~]# mosquitto_sub -t lwtest
打开第三个页签,以信息发送者角色连接 mosquitto 服务并发送消息,命令如下
## mosquitto_pub 以发送者角色连接, -t 代表主题名称, -m 代表要发送的消息内容
[root@mysql1 ~]# mosquitto_pub -t lwtest -m "hello world"
此时应该能在 第二个页签中看到 发送的消息。
三、配置管理
3.1、权限管理
vi /etc/mosquitto/mosquitto.conf 文件,关闭匿名登录、配置监听端口、配置账号文件
其中,0.0.0.0表示允许在端口 1883 上监听所有网络接口
## 关闭匿名登录
allow_anonymous false
## 监听端口。0.0.0.0表示允许在端口 1883 上监听所有网络接口
listener 1883 0.0.0.0
## 设置账户密码文件位置
password_file /etc/mosquitto/pwfile.conf
## 设置账号权限
acl_file /etc/mosquitto/aclfile.example
3.2、账号密码
上面提到账号密码存在 pwfile.conf 文件中,但刚刚安装后暂无此文件,需要基于 pwfile.example 创建。
[root@mysql1 redis-6.2.14]# cp -rf /etc/mosquitto/pwfile.example /etc/mosquitto/pwfile.conf
然后向 pwfile.conf 中追加期望的账号,命令如下(-c 参数的使用见下面代码中的说明)
## 没有 -c 参数,则会将 mqtt_read 账号追加到 pwfile.conf 中
[root@mysql1 mosquitto]# mosquitto_passwd /etc/mosquitto/pwfile.conf mqtt_read
## 若使用 -c 参数,则会清空原有 pwfile.conf 文件后,新增 mqtt_read 账号
[root@mysql1 mosquitto]# mosquitto_passwd -c /etc/mosquitto/pwfile.conf mqtt_read
执行完上述命令后,mosquitto 会立即请你提供账号的密码,请尽量给一个安全的密码吧。效果如下图所示
3.3、账号权限
如上图所示,我创建了一个 读取消息的账号 mqtt_read,一个发布消息的账号 mqtt_write,因此我会分别为它们赋予读和写的权限。修改 /etc/mosquitto/aclfile.example 文件
## 添加用户 mqtt_read
user mqtt_read
## read 订阅权限
topic read topictest/#
user mqtt_write
## write 发布权限
topic write topictest/#
## 上面的 topictest/ 的后面有一个 # 通配符,表示该路径下所有的消息
3.4、用密码登录
上面已经定义了两个账号 mqtt_read 和 mqtt_write,二者分别用于读写名为 topictest 的主题下的信息。因此再要访问 topictest 主题时,需要以如下方式分别登录用于读写的 账号
## 订阅端登录
[root@mysql1 ~]# mosquitto_sub -t testtopic -p 1883 -u 'mqtt_read' -P '123456'
## 发布端登录
[root@mysql1 ~]# mosquitto_pub -t testtopic -p 1883 -u 'mqtt_write' -P '123456' -m 'hello world!'
3.5、开机启动
命令与效果如下面所示
## 查看开机启动情况
[root@mysql1 mosquitto]# systemctl list-unit-files | grep mosquitto
## 看到的结果大概率是 disable
# 打开开机启动
[root@mysql1 mosquitto]# systemctl enable mosquitto
## 再执行第一行的命令,此时应该正常了。
四、问题与心得
4.1、开机启动异常
现象如下图所示
我按照上图的建议,使用 journalctl -xe 命令查看日志,发现如下图蓝框中比较诡异,于是我猜测是否端口冲突,但是 netstat -luntap 后没发现端口占用,然后考虑配置文件中的 listener与port的值相同。因为我在之前配置监听的时候,我不但配了 listener 是 1883,同时还把 port 打开同时配成 1883。因此当我使用 systemctl start mosquitto 的时候一直报错,但我把 port 关闭后就可以了。