常见问题汇总

常见问题的参考文档:

常见问题的快速调查方法

检查 emqx 日志是几乎每一个问题都需要做的调查步骤,是解决问题的关键。

日志介绍:日志 | EMQX 文档
日志追踪功能:日志追踪 (Trace) | EMQX 文档

连不上服务器 / 消息发送失败 / 收不到消息 / 消息重复:

  1. 客户端错误码 econnrefused 提示服务端端口没有程序监听,或者是防火墙问题;而 timeout 提示网络不通。这两种情况需要先检查客户端与服务器之间的网络状况:
    telnet <ip> <port>
    其中 <ip> 为服务端的 IP 地址,<port> 为服务端的端口号,MQTT-TCP 为 1883,MQTT-Websocket 为 8883
  2. 打开 emqx 的 debug 日志级别,或者用日志追踪功能,查看当前客户端 MQTT 消息的交互流程。
  3. 如果是订阅者收不到消息,日志里也没有给订阅者发消息相关的信息,则需要检查订阅是否成功。
  4. 使用 tcpdump 在服务端抓包调查:
    tcpdump -i any host <ip>
    其中 <ip> 为服务端的 IP 地址。

HTTP 或者其他数据集成连接失败 / 发送数据失败。

  1. 查看 emqx 日志,connrefused 字样提示端口不通,可能是服务端没有启动、偶然崩溃或者防火墙的问题。timeout 提示 emqx 与服务之前的网络不通。调查方式是:在 emqx 节点所在机器/容器上,使用 telnet <ip> <port> 命令测试网络状况。
  2. 使用 cURL 或者其他客户端工具,测试请求是否可以成功。如果可以,通过抓包对比 emqx 发送的请求与自己手动发送的有什么区别。

客户端异常断开:

  1. 使用 emqx_ctl listeners 命令调查错误码,该命令会返回每一个端口上断开原因码的统计信息。
    tcp_closed/normal:客户端主动断开
    keepalive:MQTT 的心跳检查超时,被 emqx 断开
  2. 打开 debug 日志或者日志追踪查看该 ClientID 的消息交互流程。
    • 如果发现 emqx 向其发送了多条消息之后客户端马上断开了,错误码为 tcp_closed,提示客户端可能在收到消息之后,处理过程中突然崩溃。
    • 单个连接占用内存过高可能会被 emqx 杀掉:
      • 如果是订阅者,那么可能是消费能力不足导致消息堆积,建议使用共享订阅或者改为 Webhook 收取消息。
      • 如果是发布者,是否发送过大的消息,或者是因为打开了 debug 日志导致消耗过多的内存。

emqx CPU 或者内存使用过高:

  1. 首先确定您的发布订阅场景是怎样的:
    • 多少订阅者分别订阅哪些主题?
    • 多少发布者分别向哪些主题发送消息?
    • 发布者消息速率是?
    • emqx 开启了那些功能和插件?
    • 连接的是 emqx 的 SSL 端口还是 TCP 端口?
    • 有没有发送 retain 消息?
  2. 日志中是否有错误?
  3. 使用 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.1emqx@172.16.7.3 这两个节点先行启动,以确保数据的一致性。解决方法是:

  1. 先启动这两个节点,节点就能继续启动。
  2. 如果这两个节点没有被删除,需要检查:
    • 为什么它们没有启动成功?
    • 节点之间网络有没有问题?
    • 是不是改了节点名?
  3. 如果确定这两个节点被删除了,不需要了,你可以:
    • 你再当前节点上执行 emqx_cluster_rescue force-load 命令,强制加载当前节点上的数据表;
    • 如果没有什么需要保存的数据,可以直接删除当前节点的数据目录 (data/mnesia/*),然后重启当前节点