Skip to content

消息丢失告警处理指南

消息丢失告警表示 EMQX Cloud 在消息传递过程中,由于客户端会话消息队列占满而丢弃了消息。

该情况通常意味着消息已路由到订阅者会话,但因客户端长时间离线或消息处理能力不足,导致会话消息队列达到上限,后续消息无法继续入队并被丢弃。

客户端长时间离线(Clean Session = False)

问题描述

当客户端离线且 Clean Session = False 时,EMQX Cloud 会将该客户端应接收的消息持续存入其会话消息队列(默认长度为 1000 条),等待客户端重连后投递。

如果客户端长时间未重连,导致会话过期被清理(MQTT v3 默认 2 小时,MQTT v5 由 session_expiry_interval 决定),或会话消息队列已满,则后续消息将被直接丢弃,从而触发消息丢失告警。

监控页面中,若观察到客户端处于离线状态但会话仍然存在,且消息队列已达到上限,则通常符合此类情况。

常见原因

  • 客户端离线时间过长,未及时重连。
  • 会话消息队列持续积压,达到最大长度限制。
  • 使用随机 clientid 且设置了 Clean Session = False,导致重连后会话发生变化。

处理方法

  • 若业务不需要在客户端离线期间接收消息,将 Clean Session 设置为 True,避免离线消息堆积导致丢弃。
  • 如必须使用 Clean Session = False,需确保客户端实现自动重连机制,并在断线后尽快重连。
  • 避免使用随机 clientid 搭配 Clean Session = False,以防止因 clientid 变化导致会话失效并产生消息丢弃。

客户端消息处理能力不足

问题描述

同一客户端订阅多个主题时,这些主题共用一个固定长度的会话消息队列(默认 1000 条)。如果某些主题消息流量较大,而客户端消费速度不足,会导致消息队列快速积压并达到上限,后续消息将被丢弃。

监控页面中,若客户端处于在线状态,且会话信息中显示消息队列已满(1000 / 1000),则通常符合此类情况。

常见原因

  • 客户端消息消费速度低于消息生产速度。
  • 单个客户端订阅了过多高流量主题。

处理方法

  • 优化客户端代码,提高消息处理和消费性能。
  • 使用共享订阅分摊消息负载,避免单一客户端承受过高的消息压力。相关说明可参考文档:共享订阅

排查步骤

  1. 登录 EMQX Cloud 控制台。

  2. 打开部署日志,将“错误类型”过滤为消息,查找类似如下的丢弃日志记录:

    text
    clientid: device001, peername: xx.xx.xx.xx:23853, username: test, topic: t/test, pid: <0.13552.0>, payload: 61616161616161616161, payload_encode: hex, queue: {"store_qos0":true,"max_len":1000,"len":1000,"dropped":91530}, msg: dropped_msg_due_to_mqueue_is_full
  3. 从日志中获取 clientid 信息。

  4. 打开监控 -> 客户端页面,搜索该 clientid,进入客户端详情并查看会话状态:

    • 若客户端离线但会话仍存在,则属于客户端长时间离线场景。

      message_loss_offline

    • 若客户端在线且会话消息队列已满,则属于客户端消息处理能力不足场景。

      message_loss_online

  5. 若在监控 -> 客户端页面中无法找到对应客户端会话,可结合客户端侧日志和 Clean Session(Clean Start)配置进一步判断:

    • 若设置为 True 且仍出现丢弃,通常属于客户端消息处理能力不足**。
    • 若设置为 False,则需结合客户端断连时的日志,进一步分析是否为长时间离线导致。

监控与统计

EMQX Cloud 控制台 -> 指标 -> 时间轴 -> 丢弃消息 中,可以查看基于时间轴的整体丢弃消息数量趋势,用于持续观察消息丢失情况是否得到缓解。

message_loss_monitor

消息丢弃事件追踪说明

  • EMQX Cloud 不会存储历史客户端消息队列中的完整消息内容,也不会保存已丢弃消息的全部数据。

  • 在日志中仅会记录部分关键信息(payload 可能被截断),包括 clientidpeernameusernametopicpayload 等字段。

  • 若需要长期追踪消息丢弃事件,可订阅事件主题 $events/delivery_dropped,并结合规则引擎将事件转发或存储。示例 SQL 如下:

    sql
    SELECT
        *
    FROM
        "$events/delivery_dropped"
  • 可进一步添加条件过滤,例如 clientidtopic 等字段。相关字段说明可参考:SQL 数据源和字段