消息丢失告警处理指南
消息丢失告警表示 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),则通常符合此类情况。
常见原因
- 客户端消息消费速度低于消息生产速度。
- 单个客户端订阅了过多高流量主题。
处理方法
- 优化客户端代码,提高消息处理和消费性能。
- 使用共享订阅分摊消息负载,避免单一客户端承受过高的消息压力。相关说明可参考文档:共享订阅。
排查步骤
登录 EMQX Cloud 控制台。
打开部署日志,将“错误类型”过滤为消息,查找类似如下的丢弃日志记录:
textclientid: 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从日志中获取
clientid信息。打开监控 -> 客户端页面,搜索该
clientid,进入客户端详情并查看会话状态:若客户端离线但会话仍存在,则属于客户端长时间离线场景。

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

若在监控 -> 客户端页面中无法找到对应客户端会话,可结合客户端侧日志和 Clean Session(Clean Start)配置进一步判断:
- 若设置为
True且仍出现丢弃,通常属于客户端消息处理能力不足**。 - 若设置为
False,则需结合客户端断连时的日志,进一步分析是否为长时间离线导致。
- 若设置为
监控与统计
在 EMQX Cloud 控制台 -> 指标 -> 时间轴 -> 丢弃消息 中,可以查看基于时间轴的整体丢弃消息数量趋势,用于持续观察消息丢失情况是否得到缓解。

消息丢弃事件追踪说明
EMQX Cloud 不会存储历史客户端消息队列中的完整消息内容,也不会保存已丢弃消息的全部数据。
在日志中仅会记录部分关键信息(
payload可能被截断),包括clientid、peername、username、topic和payload等字段。若需要长期追踪消息丢弃事件,可订阅事件主题
$events/delivery_dropped,并结合规则引擎将事件转发或存储。示例 SQL 如下:sqlSELECT * FROM "$events/delivery_dropped"可进一步添加条件过滤,例如
clientid、topic等字段。相关字段说明可参考:SQL 数据源和字段。