ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows 本地部署 EMQX 5.3.2:MQTT Broker 配置与避坑指南

Windows 本地部署 EMQX 5.3.2:MQTT Broker 配置与避坑指南

简介:emqx-5.3.2-windows-amd64 是面向 Windows 64 位平台的 EMQ X Broker 安装包,适合物联网开发者、后端工程师及运维人员搭建 MQTT 消息代理服务。该版本支持百万级设备并发连接、TLS/SSL 加密认证、插件扩展与 REST API,可用于智能家居、工业物联等场景的消息路由与设备管理。压缩包共 2000 个文件,约 55.9MB,以 1629 个 beam 编译文件与 106 个 app 应用描述文件为核心,辅以 js、css、html 等 Web 管理界面资源,以及 dll、pem、proto、config、bat 等运行与配置组件,结构完整、开箱即用。目前已有 1979 人学习下载。通过该资源可快速获得可运行的 Broker 服务,结合内置 Web 控制台与日志、集群管理命令,便于完成节点监控、权限配置与故障排查,是 Windows 环境下部署 MQTT 服务的实用选择。

1. 在 Windows 上把 emqx-5.3.2 跑起来:为什么我劝你先别急着改配置文件

如果你在 Windows 上做物联网平台开发,大概率绕不开 MQTT Broker 的本地部署。emqx-5.3.2-windows-amd64 这个包,就是 EMQX 5.3.2 版本针对 Windows 64 位系统的免安装压缩包。下载解压后,目录里直接带着bin、etc、data、log这些标准结构,不需要走安装向导,也不需要额外装 Erlang 运行时——它已经把依赖打包进去了。这意味着你可以把它丢进任意目录,改完监听端口和认证配置就能当本地测试 Broker 用。适合谁?做设备接入联调的后端、写 MQTT 客户端 SDK 的移动端开发、以及需要在内网快速搭一套消息总线做验证的嵌入式团队。但我要先说一个反直觉的结论:这个包最容易翻车的地方不是性能,而是 Windows 下的路径、防火墙和配置文件编码。下面按我实际拆包复现的顺序,把每一步和对应的坑讲清楚。

2. 解压与首次启动:目录结构、端口占用与启动脚本

2.1 解压后的目录里到底有什么

把emqx-5.3.2-windows-amd64.zip解压到任意非中文、非空格路径下,比如D:\emqx。解压后你会看到这几个关键目录:

目录/文件作用新手容易忽略的点
bin/启动、停止、控制台命令必须用管理员权限运行emqx.cmd
etc/主配置emqx.conf和认证插件配置5.x 版本配置格式与 4.x 完全不同
data/运行时数据、Mnesia 数据库、认证数据删除后认证用户会丢失
log/运行日志,排错第一现场启动失败先看log/emqx.log
releases/版本信息和启动脚本依赖不要手动改里面的文件

常见做法是直接把整个文件夹放到C:\emqx或D:\emqx。注意:路径里不要出现中文、空格或特殊符号,否则 Erlang 虚拟机在解析路径时可能直接报错退出,这是 Windows 下最典型的玄学问题之一。

2.2 启动命令与端口检查

EMQX 5.3.2 在 Windows 下没有图形化启动器,必须走命令行。打开 PowerShell 或 CMD,以管理员身份执行:

# 进入解压目录的 bin 文件夹 cd D:\emqx\bin # 前台启动,方便直接看输出日志 emqx.cmd console # 或者后台启动(推荐用于长期测试) emqx.cmd start

启动后,默认会监听以下端口:

  • 1883:MQTT TCP 协议端口
  • 8083:MQTT over WebSocket 端口
  • 8883:MQTT over SSL 端口
  • 18083:Dashboard 管理界面端口

用netstat -ano | findstr "1883 18083"检查端口是否被占用。如果 1883 被占用,启动会失败,日志里会写eaddrinuse。这时候要么停掉占用进程,要么改etc/emqx.conf里的listeners.tcp.default.bind值。

提示:第一次启动时 Windows 防火墙会弹窗询问是否允许网络访问,必须勾选“专用网络”和“公用网络”,否则局域网内其他设备连不上 1883 端口。

2.3 验证 Broker 是否真的活了

启动成功后,浏览器打开http://127.0.0.1:18083,默认账号admin,密码public。登录后会强制要求改密码,这是 5.x 版本的安全策略。改完后进入 Dashboard,在“连接”菜单里能看到当前客户端列表。

如果你不想开浏览器,也可以用命令行发一条 MQTT 消息验证。Windows 下我一般用mosquitto_pub这个轻量客户端:

# 订阅主题 test/topic mosquitto_sub -h 127.0.0.1 -p 1883 -t "test/topic" -v # 另开一个窗口发布消息 mosquitto_pub -h 127.0.0.1 -p 1883 -t "test/topic" -m "hello emqx"

订阅窗口收到test/topic hello emqx就说明 Broker 收发正常。这一步能过,后面再折腾认证和桥接才有意义。

3. 配置文件怎么改:从 4.x 迁移到 5.3.2 的语法差异

3.1 emqx.conf 的结构变了

EMQX 5.x 把配置体系换成了 HOCON 格式,和 4.x 的key = value扁平结构不兼容。很多人拿着 4.x 的配置直接往 5.3.2 里贴,结果启动报unknown config。5.3.2 的etc/emqx.conf长这样:

# 节点名称,Windows 下默认是 emqx@127.0.0.1 node { name = "emqx@127.0.0.1" cookie = "emqxsecretcookie" data_dir = "data" } # 监听器配置,注意这里是嵌套结构 listeners.tcp.default { bind = "0.0.0.0:1883" max_connections = 1024000 } # Dashboard 配置 dashboard { listeners.http { bind = 18083 } default_username = "admin" default_password = "public" }

改端口就改bind字段,改最大连接数就改max_connections。注意node.cookie是集群通信用的,单机测试不用动,但如果要搭集群,所有节点的 cookie 必须一致。

3.2 认证配置:不要直接改 emqx.conf

5.3.2 把认证和授权拆到了独立的配置文件里,路径是etc/emqx.conf同级目录下的authn和authz相关配置。但更推荐的做法是通过 Dashboard 的“访问控制”菜单来配,因为 Dashboard 改完会自动写入data/configs/cluster.hocon,不会污染主配置。

如果你非要手改,内置数据库认证的配置片段如下:

# 在 emqx.conf 中追加 authentication 块 authentication = [ { backend = "built_in_database" mechanism = "password_based" password_hash_algorithm { name = "sha256" salt_position = "suffix" } user_id_type = "username" } ]

这段配置的意思是:启用内置数据库做用户名密码认证,密码用 SHA256 加盐哈希存储,盐值放在密码后缀。改完必须执行emqx.cmd stop再emqx.cmd start,热重载在 Windows 下经常不生效。

3.3 用 Dashboard 加用户比手改配置快

我一般会走 Dashboard 这条路:登录 18083 → 访问控制 → 认证 → 创建认证器 → 选 Password-Based → 选 Built-in Database → 创建。然后在“用户管理”里手动加几个测试账号。这样做的另一个好处是,用户数据存在data/mnesia里,重启不丢,而手改配置文件容易因为编码问题导致中文用户名乱码。

注意:Windows 下用记事本编辑emqx.conf会默认存成 UTF-8 with BOM,EMQX 解析时会报unexpected byte order mark。一定要用 VS Code 或 Notepad++ 存成无 BOM 的 UTF-8。

4. 避坑与排查:Windows 下最容易翻车的五个场景

4.1 启动闪退,日志里只有一行{"init terminating in do_boot",...}

现象:双击emqx.cmd窗口一闪而过,或者emqx.cmd console输出几行就退出。

原因:九成是路径问题。Erlang 虚拟机对 Windows 路径中的中文、空格、括号极其敏感。比如你把包解压到了C:\Users\张三\Downloads\emqx-5.3.2-windows-amd64,用户名带中文,直接挂。

解决:把整个文件夹移到D:\emqx或C:\emqx这种纯英文短路径下。如果已经移了还报错,检查data目录下是否有上次启动残留的mnesia锁文件,删掉data/mnesia整个目录再启动。

4.2 Dashboard 能打开,但 1883 端口连不上

现象:浏览器访问 18083 正常,但 MQTT 客户端连接 1883 超时。

原因:Windows 防火墙拦截了 1883 入站,或者emqx.conf里listeners.tcp.default.bind被改成了127.0.0.1:1883,只监听本地回环。

解决:先检查防火墙入站规则,给emqx.cmd或erl.exe放行 1883 端口。然后确认bind值是0.0.0.0:1883,这样局域网内其他机器才能连。改完配置记得emqx.cmd stop再start。

4.3 认证用户加了,但客户端还是能匿名登录

现象:在 Dashboard 里创建了认证器,也加了用户,但用任意用户名密码都能连上。

原因:5.3.2 默认有一个allow_anonymous的兜底规则,认证器没匹配到时会走匿名放行。需要在认证器配置里把“认证失败时”的行为改成拒绝。

解决:Dashboard → 访问控制 → 认证 → 编辑你的认证器 → 把“失败时”从ignore改成deny。或者在emqx.conf的authentication块后面加authorization.no_match = deny。

4.4 日志文件暴涨,磁盘几天就满了

现象:log/emqx.log每天涨几个 GB,C 盘告急。

原因:默认日志级别是warning,但如果你开了 debug 或者有大量客户端频繁重连,日志会疯狂写。

解决:改etc/emqx.conf里的log.file.level为error,并设置log.file.rotation.size和log.file.rotation.count限制单个文件大小和保留数量:

log.file { level = "error" rotation.size = "50MB" rotation.count = 5 }

这样最多占 250MB,不会把盘写满。

4.5 用emqx.cmd stop停不掉,进程残留

现象:执行停止命令后,任务管理器里还有erl.exe进程,端口没释放。

原因:Windows 下emqx.cmd stop依赖node.cookie和节点名匹配,如果你改过node.name或node.cookie,停止命令找不到目标节点。

解决:先用emqx.cmd ping看节点是否响应。如果没响应,直接任务管理器结束erl.exe,然后删掉data/mnesia下的锁文件再启动。更稳妥的做法是别改node.name,保持默认的emqx@127.0.0.1。

5. 进阶技巧:用内置规则引擎做消息桥接与验证

5.1 规则引擎能干什么

EMQX 5.3.2 内置了 SQL 风格的规则引擎,可以在 Broker 层面直接做消息过滤、转换和转发,不用写外部消费者。比如你想把所有发往sensor/+/temperature的消息,转发到alert/high_temp主题,同时只保留温度大于 80 的数据,用一条规则就能搞定。

5.2 在 Dashboard 里配一条规则

进入 Dashboard → 集成 → 规则 → 创建。SQL 写:

SELECT payload.temp as temp, clientid, topic FROM "sensor/+/temperature" WHERE payload.temp > 80

然后添加一个动作:消息重发布,目标主题写alert/high_temp,Payload 用${temp}和${clientid}拼。保存后启用规则。

5.3 用 MQTT 客户端验证规则是否生效

开两个订阅窗口,一个订阅sensor/+/temperature,一个订阅alert/high_temp。然后发布一条温度 90 的消息:

mosquitto_pub -h 127.0.0.1 -p 1883 -t "sensor/room1/temperature" -m '{"temp":90}'

如果alert/high_temp窗口收到消息,说明规则生效。再发一条温度 50 的,alert/high_temp不应该收到。这一步验证的是 SQL 里的WHERE条件是否被正确解析。

5.4 规则引擎的调试黑匣子

规则执行失败时,Dashboard 的“规则”页面会显示命中次数和失败次数。点进规则详情,能看到最近几条失败记录和错误原因。我一般会先看SELECT语句里的字段路径对不对——比如payload.temp要求消息体是 JSON 格式,如果你发的是纯文本90,payload.temp就是undefined,规则不会报错但也不会命中。这时候要么改 SQL 用payload直接取原始值,要么让发布端发 JSON。

5.5 一个我踩过的坑:规则重发布导致消息循环

有一次我配了一条规则,把alert/#的消息重发布到alert/archive,结果alert/archive也匹配alert/#,消息无限循环,Broker CPU 直接跑满。后来在 SQL 里加了WHERE topic != 'alert/archive'才解决。从那以后我每次配重发布规则,都强制走一遍“目标主题是否会被源主题匹配”的检查。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进