MQTT 客户端出现连接订阅等问题时如何排查?

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 这是一期EMQX社区专题FAQ,我们整理了近期社区中关注度较高的问题,在这里进行统一汇总解答。

大家好,这是一期社区专题 FAQ。我们整理了近期社区中关注度较高的问题,在这里进行统一汇总解答。

今后本系列内容将不定期推送,敬请关注。

同时,如果大家在使用 EMQX 的过程中遇到问题,欢迎通过以下方式进行解决:

  • 查阅 EMQX 产品文档博客文章。
  • 如果在现有资料中未能查询到问题的解决办法,可以在问答社区中留言提问,我们会尽快解答您的问题。

Q:向 MQTT Broker 发布多条消息,MQTT Broker 向订阅者转发这些消息的时候能否保证原始顺序?

MQTT Broker 一定会保证来自同一客户端的相同主题的消息按照到达顺序被转发,这与消息的 QoS 等级无关,QoS 等级不会影响转发顺序,不管是消息丢失,还是消息重复,也都不会导致消息失序。

对于不同主题的消息,MQTT Broker 不会提供转发顺序保证,我们可以将他们视为进入了不同的通道,比如主题 A 的消息先于主题 B 的消息到达 MQTT Broker,但最终可能主题 B 的消息会更早下发。

Q:我的客户端无法连接到 EMQX/订阅失败/发布消息但是对端没有收到任何消息,出现这些情况怎么办?

A:其实 EMQX 的 Debug 日志基本已经记录了所有的行为和现象,通过阅读 Debug 日志我们能够知道客户端何时发起了连接,连接时指定了哪些字段,连接是否通过,被拒绝连接的原因是什么等等。但是由于 Debug 日志记录的信息过多,会带来额外的资源消耗,并且不利于我们针对单个客户端或主题进行分析。

所以 EMQX 提供了日志追踪功能,我们可以指定想要追踪的客户端或主题,EMQX 会将所有与该客户端或主题相关的 Debug 日志都输出到指定日志文件中。这样不管是自己分析调试,还是寻求社区帮助,都会方便许多。

Q:为什么会有 Client ID 为 CENSYS 的或者是其他我不认识的客户端?

A:CENSYS 是一款互联网探测扫描工具,它会周期性扫描 IPv4 地址空间,探测 HTTP、SSH、MQTT 等协议的默认端口。所以如果你发现有 Client ID 为 CENSYS 的或者其他未知的客户端接入了你的 MQTT Broker,这意味你目前处于相对较低的安全性保障下。以下措施可以有效帮助你避免这个问题:

  1. 不要使用默认配置,例如 EMQX 用于验证 HTTP API 访问权限的 AppID 与 AppSecret 等
  2. 启用认证,可以是用户名密码认证,也可以是 JWT 认证,避免只需要知道 IP 地址就可以登录的尴尬情况
  3. 启用 TLS 双向认证,只有持有有效证书的客户端才能接入系统
  4. 启用授权,避免非法设备登录后可以获取敏感数据
  5. 配置你的防火墙,尽量关闭一些不需要的端口

Q:EMQX 是一个主题一个消息队列吗?

A:不是。EMQX 中的每个客户端进程都会有一个消息队列,这个消息队列会存储所有因飞行窗口满或连接断开而暂时无法下发给客户端的消息。消息队列有最大长度限制,以避免消息无限制堆积,达到最大长度后,为了使新消息继续入队,EMQX 会陆续丢弃队列中最老的消息。消息队列最大长度由 max_mqueue_len 这个配置项指定。

Q:EMQX 日志中出现 "Parse failed for function_clause" 是什么原因?

A:这个日志表示报文解析失败,可能因为这不是一个 MQTT 报文,我们遇到过很多向 MQTT 端口发送 HTTP 请求的情况,也可能因为报文中包含了非 UTF-8 字符等等。我们可以在这条 "Parse failed..." 日志中检索 Frame data 关键字以查看完整的报文,帮助我们分析解析失败的可能原因。

Q:EMQX 日志中出现 "Context: maximum heap size reached" 是什么原因?

A:出现这个日志通常表示相应的客户端进程已经达到了最大堆栈内存占用限制,之后这个进程就会被 EMQX 强制 Kill。这一机制存在的原因是为了保证 EMQX 的可用性,避免客户端进程的内存占用无限制增长最终导致 EMQX OOM。客户端进程的堆栈占用主要来源于飞行窗口和消息队列中未完成确认或未投递的消息,而这两处消息堆积的主要原因通常是客户端消费能力不足,无法及时处理响应消息。

与此相关的配置项是 force_shutdown_policy,它的配置格式为 <Maximum Message Queue Length>|<Maximum Heap Size>,例如 10000|64MB。其中 <Maximum Heap Size> 就是限制每个客户端进程能够占用的最大堆栈内存。

我们见过一些用户为了不想客户端进程被强制关闭,不去提升客户端的消费能力,而是一味增大 <Maximum Heap Size>,这除了给 EMQX 带来 OOM 风险,也会使得消息的时延增加,往往得不偿失。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/mqtt-client-faq

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
1月前
|
消息中间件 测试技术
通过轻量消息队列(原MNS)主题HTTP订阅+ARMS实现自定义数据多渠道告警
轻量消息队列(原MNS)以其简单队列模型、轻量化协议及按量后付费模式,成为阿里云产品间消息传输首选。本文通过创建主题、订阅、配置告警集成等步骤,展示了该产品在实际应用中的部分功能,确保消息的可靠传输。
44 2
|
5月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
4月前
|
物联网 C# 智能硬件
智能家居新篇章:WPF与物联网的智慧碰撞——通过MQTT协议连接与控制智能设备,打造现代科技生活的完美体验
【8月更文挑战第31天】物联网(IoT)技术的发展使智能家居设备成为现代家庭的一部分。通过物联网,家用电器和传感器可以互联互通,实现远程控制和状态监测等功能。本文将探讨如何在Windows Presentation Foundation(WPF)应用中集成物联网技术,通过具体示例代码展示其实现过程。文章首先介绍了MQTT协议及其在智能家居中的应用,并详细描述了使用Wi-Fi连接方式的原因。随后,通过安装Paho MQTT客户端库并创建MQTT客户端实例,演示了如何编写一个简单的WPF应用程序来控制智能灯泡。
151 0
|
4月前
|
消息中间件 Arthas Java
RocketMQ—一次连接namesvr失败的案例分析
项目组在使用RocketMQ时遇到Consumer连接Name Server失败的问题,异常显示连接特定地址失败。通过Arthas工具逐步分析代码执行路径,定位到创建Channel返回空值导致异常。进一步跟踪发现,问题源于Netty组件在初始化`ByteBufAllocator`时出现错误。分析依赖后确认存在Netty版本冲突。解决方法为排除冲突的Netty包,仅保留兼容版本。
300 0
RocketMQ—一次连接namesvr失败的案例分析
|
5月前
|
消息中间件 Java 物联网
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
|
4月前
|
安全 网络性能优化
MQTT 客户端 MQTT.fx 使用说明
MQTT 客户端 MQTT.fx 使用说明
413 0
|
5月前
|
消息中间件 JavaScript Linux
消息队列 MQ操作报错合集之客户端在启动时遇到了连接错误,是什么原因
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 JSON Java
开发者如何使用轻量消息队列MNS
【10月更文挑战第19天】开发者如何使用轻量消息队列MNS
101 8
|
2月前
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
94 8
|
1月前
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。