MQTT over QUIC - EMQX5&NanoMQ 安装配置
桥接拓扑图(个人理解)
安装配置EMQX5服务器
安装服务器
由于是实验性功能,在 CentOS 6、macOS 以及 Windows 系统下并未包含 QUIC 编译,我们跟从官网的推荐从源码编译并在编译前指定环境变量 BUILD_WITH_QUIC=1。我们也使用推荐的Docker环境。
Docker Desktop on Windows下载页面
我的docker是在Windows11里安装的。安装完成后如下图
用管理员打开cmd,输入如下指令以获取docker镜像
docker pull emqx/emqx:5.2.1
运行以下命令启动 Docker 容器。
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 -p 14567:14567/udp -e EMQX_LISTENERS__QUIC__DEFAULT__keyfile="etc/certs/key.pem" -e EMQX_LISTENERS__QUIC__DEFAULT__certfile="etc/certs/cert.pem" -e EMQX_LISTENERS__QUIC__DEFAULT__ENABLED=true -e BUILD_WITH_QUIC=1 emqx/emqx:5.2.1
运行得到下图,但是其中的Listener quic:default on 0.0.0.0:14567 started.
是Listener quic:default on :14567 started.
需要做下面的修改
配置服务器
找到Files
里面的/opt/emqx/etx/emqx.conf
,鼠标右键选择Edit file
将下文粘贴到emqx.conf
之后
# etc/emqx.conf
listeners.quic.default {
enabled = true
bind = "0.0.0.0:14567"
max_connections = 1024000
keyfile = "etc/certs/key.pem"
certfile = "etc/certs/cert.pem"
}
重启docker,就会正常开启QUIC了,也会正常出现Listener quic:default on 0.0.0.0:14567 started.
了
至此,服务器配置完毕。
安装配置客户端NanoMQ
NanoMQ 也是需要编译时手动开启QUIC,而且只支持桥接模式。
安装VMware 16
安装Ubuntu 22.04.3 desktop
安装NanoMQ
打开终端,输入如下指令。
cd
git clone https://github.com/emqx/nanomq.git
cd nanomq
## 使用国内网络拉取 MSQUIC submodule 可能耗时较久
## 如若出现网络问题,可以考虑梯子、代理等方式
git submodule update --init --recursive
mkdir build
cd build
## 默认编译`msquic`为动态库,如需设置编译目标为静态库则添加 cmake 编译选项 `-DQUIC_BUILD_SHARED=OFF`
cmake -G Ninja -DNNG_ENABLE_QUIC=ON ..
sudo ninja install
我下载的是v0.20.0,如若更新,下载该版本请参考github的官方位置,如下图。
下载之后解压即可。
此外,在此下载的如若没有.git
文件夹,在执行git submodule update --init --recursive
时会报错,此时我的操作是从git clone https://github.com/emqx/nanomq.git
这个指令得到的高版本的.git
文件夹复制到解压后的文件夹,而后再执行git submodule update --init --recursive
即可。
配置NanoMQ桥接
启动 QUIC 模组后,需要在 nanomq/etc/nanomq.conf
文件中配置 MQTT over QUIC 桥接功能和对应的主题,例如,在下面的配置文件中,定义了 MQTT over QUIC 桥接的服务器地址、连接凭证、连接参数、消息转发规则、订阅主题和队列长度等内容。把下面这段代码添加到 nanomq/etc/nanomq.conf
文件后面即可。
bridges.mqtt.name {
## TCP URL 格式: mqtt-tcp://host:port
## TLS URL 格式: tls+mqtt-tcp://host:port
## QUIC URL 格式: mqtt-quic://host:port
## 我的EMQX的IP为192.168.43.54,开的quic端口号为14567
server = "mqtt-quic://192.168.43.54:14567"
proto_ver = 4
username = dyx #用户名
password = dyx #密码
clean_start = true
keepalive = 60s
## forwards -- 转发远端 Topic 数组(支持 MQTT 通配符)
forwards = [
{
remote_topic = "fwd/topic1"
local_topic = "topic1"
qos = 0
},
{
remote_topic = "fwd/topic2"
local_topic = "topic2"
qos = 0
}
]
quic_keepalive = 120s
quic_idle_timeout = 120s
quic_discon_timeout = 20s
quic_handshake_timeout = 60s
hybrid_bridging = false
## subscription -- 订阅远端 Topic 数组(支持 MQTT 通配符)
subscription = [
{
remote_topic = "cmd/topic1"
local_topic = "topic3"
qos = 0
},
{
remote_topic = "cmd/topic2"
local_topic = "topic4"
qos = 0
}
]
max_parallel_processes = 2
max_send_queue_len = 1024
max_recv_queue_len = 1024
}
启动NanoMQ
打开一个新的终端——终端A,进入到/nanomq/build/nanomq
输入以下代码
./nanomq start
如若出现以下信息,则代表成功启动
NanoMQ Broker is started successfully!
测试桥接
NanoMQ (即终端A)在测试过程中不要关闭
测试消息转发
为 EMQX 订阅转发主题 “fwd/#”,用于接收由 NanoMQ转发的数据:
打开一个新的终端——终端B,进入到/nanomq/build/nanomq_cli
输入以下代码
./nanomq_cli sub --quic -h "192.168.43.54" -t "fwd/#" -q 0
注:
./nanomq_cli
的参数含义## -h {host} ## -p {端口号,如不指定将使用默认端口号 1883(MQTT)或 14567(QUIC)} ## -t {主题名称} ## --quic {开启 quic} ## -q {消息 QoS,可选值 0、1、2} ## --m {消息 payload} ## -u {用户名} ## -P {密码}
得到以下输出,则代表quic连接成功
quic_connect_cb: mqtt-quic://192.168.43.54:14567 connect
新建一个终端——终端C,发布消息到 NanoMQ ,主题为 “fwd/topic1”:
./nanomq_cli pub -h "192.168.233.132" -t "fwd/topic1" -m "123456" -q 0
192.168.233.132是我的NanoMQ的主机的IP
之后终端C输出
connect_cb: mqtt-tcp://192.168.233.132:1883 connect result: 0
disconnected reason : 0
同时终端A输出
2023-10-25 14:46:07 [7195] WARN /home/zxx/nanomq/nng/src/sp/transport/mqtt/broker_tcp.c:612 tcptran_pipe_recv_cb: nni aio recv error!! Connection shutdown
2023-10-25 14:46:07 [7195] WARN /home/zxx/nanomq/nng/src/sp/transport/mqtt/broker_tcp.c:880 tcptran_pipe_recv_cb: tcptran_pipe_recv_cb: parse error rv: 139
显然是NanoMQ拒绝了tcp的连接,具体原因不知道为什么。
测试消息接收
为 NanoMQ 订阅主题 “cmd/topic1”,用于接收 EMQX 发布的数据:
在终端C中,执行以下命令进行订阅:
./nanomq_cli sub -h "192.168.233.132" -t "cmd/topic1" -q 0
有如下输出表示订阅成功
connect_cb: mqtt-tcp://192.168.233.132:1883 connect result: 0
在终端B中,发布消息到远端 EMQX Broker,主题为 “cmd/topic1”:
./nanomq_cli pub --quic -h "192.168.43.54" -t "cmd/topic1" -m "cmd_msg" -q 0 -u dyx -P dyx
但是得到如下输出
quic_connect_cb: mqtt-quic://192.168.43.54:14567 connect
bridge client disconnected!
并不知道原因。
Wireshark抓包分析
在测试消息转发中,输入./nanomq_cli sub --quic -h "192.168.43.54" -t "fwd/#" -q 0
时,进行抓包,会得到一系列的QUIC、TCP、HTTP等报文,进行过滤器筛选,得到下图数据包,可以用来分析QUIC的连接过程,但是如若像分析数据转发订阅的过程,则需要进一步配置,但我还没有具体操作成功。