常见问题的参考文档:
问题分类 | 文档 |
---|---|
SSL 相关 | 网络与 TLS | EMQX 文档 EMQX MQTT 服务器启用 SSL/TLS 安全连接 | EMQ |
日志 | 日志 | EMQX 文档 |
性能测试、系统调优 | 系统调优 | EMQX 文档 |
配置文件 | https://www.emqx.io/docs/zh/latest/configuration/configuration-manual.html |
HTTP 接口的调用和认证方式 | REST API | EMQX 文档 |
HTTP 接口文档 | EMQX v5.3 API Documentation |
常见问题与解答 | 常见问题解答 | EMQX 文档 |
常见问题的快速调查方法
检查 emqx 日志是几乎每一个问题都需要做的调查步骤,是解决问题的关键。
日志介绍:日志 | EMQX 文档
日志追踪功能:日志追踪 (Trace) | EMQX 文档
连不上服务器 / 消息发送失败 / 收不到消息 / 消息重复:
- 客户端错误码 econnrefused 提示服务端端口没有程序监听,或者是防火墙问题;而 timeout 提示网络不通。这两种情况需要先检查客户端与服务器之间的网络状况:
telnet <ip> <port>
其中<ip>
为服务端的 IP 地址,<port>
为服务端的端口号,MQTT-TCP 为 1883,MQTT-Websocket 为 8883 - 打开 emqx 的 debug 日志级别,或者用日志追踪功能,查看当前客户端 MQTT 消息的交互流程。
- 如果是订阅者收不到消息,日志里也没有给订阅者发消息相关的信息,则需要检查订阅是否成功。
- 使用 tcpdump 在服务端抓包调查:
tcpdump -i any host <ip>
其中<ip>
为服务端的 IP 地址。
HTTP 或者其他数据集成连接失败 / 发送数据失败。
- 查看 emqx 日志,connrefused 字样提示端口不通,可能是服务端没有启动、偶然崩溃或者防火墙的问题。timeout 提示 emqx 与服务之前的网络不通。调查方式是:在 emqx 节点所在机器/容器上,使用
telnet <ip> <port>
命令测试网络状况。 - 使用 cURL 或者其他客户端工具,测试请求是否可以成功。如果可以,通过抓包对比 emqx 发送的请求与自己手动发送的有什么区别。
客户端异常断开:
- 使用
emqx_ctl listeners
命令调查错误码,该命令会返回每一个端口上断开原因码的统计信息。
tcp_closed/normal:客户端主动断开
keepalive:MQTT 的心跳检查超时,被 emqx 断开 - 打开 debug 日志或者日志追踪查看该 ClientID 的消息交互流程。
- 如果发现 emqx 向其发送了多条消息之后客户端马上断开了,错误码为 tcp_closed,提示客户端可能在收到消息之后,处理过程中突然崩溃。
- 单个连接占用内存过高可能会被 emqx 杀掉:
- 如果是订阅者,那么可能是消费能力不足导致消息堆积,建议使用共享订阅或者改为 Webhook 收取消息。
- 如果是发布者,是否发送过大的消息,或者是因为打开了 debug 日志导致消耗过多的内存。
emqx CPU 或者内存使用过高:
- 首先确定您的发布订阅场景是怎样的:
- 多少订阅者分别订阅哪些主题?
- 多少发布者分别向哪些主题发送消息?
- 发布者消息速率是?
- emqx 开启了那些功能和插件?
- 连接的是 emqx 的 SSL 端口还是 TCP 端口?
- 有没有发送 retain 消息?
- 日志中是否有错误?
- 使用 observer_cli 调查系统是否存在瓶颈:
emqx eval 'observer_cli:start()'
然后按 mm 或者 mq 并回车,分别按内存或者进程队列长度排序
集群中某个节点无法启动:
[warning] ... is waiting for one of the nodes: [‘emqx@172.16.7.1’, ‘emqx@172.16.7.3’]
该日志表示当前节点还在等待 emqx@172.16.7.1
,emqx@172.16.7.3
这两个节点先行启动,以确保数据的一致性。解决方法是:
- 先启动这两个节点,节点就能继续启动。
- 如果这两个节点没有被删除,需要检查:
- 为什么它们没有启动成功?
- 节点之间网络有没有问题?
- 是不是改了节点名?
- 如果确定这两个节点被删除了,不需要了,你可以:
- 你再当前节点上执行
emqx_cluster_rescue force-load
命令,强制加载当前节点上的数据表; - 如果没有什么需要保存的数据,可以直接删除当前节点的数据目录 (
data/mnesia/*
),然后重启当前节点
- 你再当前节点上执行