资讯动态

Mosquitto 1.6.12 / 1.5.10 版本解析:QoS 2 内存泄漏修复、CONNACK 退出码与命令行客户端行为改进

发布时间:2026/9/26 15:49:09 来源:尧图企业网站定制
物联网消息队列后端网络/通信【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mo/mosquitto点击查看免费下载Mosquitto 1.6.12 与 1.5.10 于 2020-08-19 同日发布见 ChangeLog.txt其中 1.5.10 仅包含安全修复Broker 与 Clients 的改进只适用于 1.6.12。本文以该发布说明为主体结合当前仓库源码Broker 消息队列、配置解析、客户端发布/订阅实现逐条解析此次发布的核心内容QoS 2 消息内存泄漏的触发场景与底层队列机制、max_queued_messages等队列参数的实战配置、WITH_BRIDGEno/WITH_TLSno的编译警告修复以及mosquitto_pub/mosquitto_sub在 CONNACK 失败退出码与-l慢连接场景下的行为改进。读完本文你将能够准确评估该安全补丁的影响范围并在自己的部署中合理配置队列上限以规避同类风险。发布背景1.6.12 与 1.5.10 的版本对应关系本次发布同时推出两条维护分支的新版本1.6.12包含安全修复、Broker 编译警告修复与 Clients 行为改进1.5.10仅包含安全修复其余两项改进不适用于 1.5 分支。两条分支共用的安全修复针对同一个问题GitHub issue #1793而 Broker 与 Clients 的改动明确标注适用于 1.6.12 only。这一划分意味着如果生产环境仍停留在 1.5 系列本次升级的核心诉求是安全补丁如果使用 1.6 系列则可同时获得客户端可用性改进。安全修复特定场景下处理 PUBLISH 消息的内存泄漏触发条件组合发布说明给出的泄漏场景具有相当严格的组合条件缺一不可入站消息为 QoS 2泄漏只出现在处理入站 QoS 2 PUBLISH 消息的路径上Broker 启用了持久化persistence true客户端使用 clean sessionfalse 连接且在 Broker 重启之前就已连接该客户端在 Broker 重启后重新连接并以足够高的速率持续发送消息高消息速率导致 Broker 的入站队列被填满消息开始被丢弃该问题在max_queued_messages取较小值时更容易显现。其本质是消息被丢弃时与 QoS 2 消息关联的内存没有被正确释放形成累积式泄漏。该问题已在此次发布中修复Closes #1793。底层机制入站队列与配额判定要理解该场景需要看 Broker 是如何决定是否允许消息进入队列的。在 src/database.c 中两个核心函数负责该判定db__ready_for_flight()判断消息是否允许进入 inflight在途状态。对 QoS 0 消息队列满时直接丢弃对 QoS 1/2 消息则依据max_inflight_messages、max_inflight_bytes与max_queued_messages/max_queued_bytes的组合条件判定src/database.c。db__ready_for_queue()在 inflight 检查通过之后判断是否还有余量将消息写入队列。其判定逻辑同样组合了max_queued_bytes与max_queued_messages两个上限src/database.c。在消息入站处理侧src/handle_publish.c 的process_bad_message路径展示了队列已满的直接后果当context-out_packet_count db.config-max_queued_messages时Broker 会以MQTT_RC_QUOTA_EXCEEDED拒绝消息。结合上述条件可以推断当入站 QoS 2 消息在持久化、非干净会话重启重连的组合下被丢弃时其消息体与关联属性所占内存若未随丢弃动作一并释放就会形成发布说明中描述的内存泄漏。这也是为什么该问题与max_queued_messages的取值强相关——值越小队列越早填满丢弃行为越频繁泄漏越容易被观察到。队列相关配置参数详解与本次安全修复直接相关的配置项在 mosquitto.conf 中有完整说明配置项默认值含义max_queued_messages1000每个客户端在 in-flight 之外最多排队持有的 QoS 1/2 消息数设为 0 表示无上限不推荐max_queued_bytes0每个客户端排队消息的总字节上限默认 0 表示无上限。当与max_queued_messages同时设置时先达到任一上限即停止入队queue_qos0_messagesfalse是否允许为离线的非干净会话客户端排队 QoS 0 消息配合max_queued_messages/max_queued_bytes生效max_inflight_messages20每个客户端允许同时在途的 QoS 1/2 消息数默认值 1000 定义于配置初始化函数config__init()中src/conf.c其解析入口位于conf__parse对max_queued_messagestoken 的分支处理src/conf.c。关于排队策略需要特别澄清两点依据 src/database.c 与 src/database.c 的注释与实现QoS 0 消息没有排队选项除非客户端离线且queue_qos0_messages已启用——队列满时 QoS 0 消息要么直接投递要么被丢弃QoS 1/2 消息会先占用 inflight 配额超出部分才进入 per-client 队列离线客户端的队列计算会剔除 in-flight 调整量src/database.c。对生产环境的启示若你的部署启用了持久化并允许大量非干净会话客户端应避免将max_queued_messages设置得过小同时可配合max_queued_bytes从字节维度限制内存占用双上限可互相兜底。修复范围的验证方式该修复同时进入 1.6.12 与 1.5.10 两条分支发布说明与 ChangeLog.txt 的记录一致。升级后可通过长时间运行观察 Broker 进程 RSS 是否在高消息速率 队列打满 消息丢弃场景下保持平稳来验证修复效果。若仍需在低内存设备上严格控制队列深度建议同时关注max_queued_bytes它是从字节维度限制每客户端排队内存的补充手段。BrokerWITH_BRIDGEno/WITH_TLSno编译警告修复1.6.12 修复了在禁用桥接与 TLS 功能时构建 Broker 产生的编译警告WITH_BRIDGEno关闭桥接bridge模式支持WITH_TLSno关闭 TLS 支持。这两个开关定义于构建配置 config.mk 中其中WITH_TLS默认yesWITH_BRIDGE默认yes可通过make WITH_BRIDGEno WITH_TLSno等方式覆盖。关闭后编译系统通过LOCAL_CPPFLAGS注入-DWITH_BRIDGE/-DWITH_TLS等宏config.mk源码中对应功能块以条件编译隔离。此项改动属于构建质量改进而非功能性变更意义在于面向资源受限环境如仅作本地轻量 Broker裁剪功能编译时不再被警告刷屏方便维护者更清晰地发现真正的编译问题。ClientsCONNACK 失败时以错误退出码退出1.6.12 修复了客户端在 CONNACK连接确认失败时错误地以成功状态退出的问题Closes #1778。此前mosquitto_pub、mosquitto_sub、mosquitto_rr等客户端在连接被拒时可能返回零退出码导致脚本、CI 与守护进程管理工具误判连接成功。修复后所有客户端在 CONNACK 失败时统一以非零退出码结束。从当前源码可以印证该行为的两条路径在mosquitto_pub的发布循环中连接失败会把状态置为STATUS_NOHOPEclient/pub_client.c随后在 client/pub_client.c 直接返回MOSQ_ERR_CONN_REFUSED从而令进程以失败码退出在mosquitto_sub侧超时或收到中断信号且尚未收到 CONNACK 时直接调用exit(-1)client/sub_client.c。对运维脚本的直接影响以mosquitto_pub -h host -t topic -m msg这类命令的返回值作为健康检查依据的场景现在可以可靠区分连接被拒/认证失败与消息发送成功两种结果。Clients修复mosquitto_pub -l在慢连接上的忙循环mosquitto_pub -l等价于--stdin-line参数解析见 client/client_shared.c表示逐行读取标准输入每行发布一条独立消息直到 EOF 结束。其核心实现在pub_stdin_line_loop()client/pub_client.c。1.6.12 修复了该模式在慢连接下可能出现的忙循环busy loop问题当连接缓慢或发送受阻时程序可能持续占用 CPU 空转而不是等待网络就绪。从当前实现可见其状态机设计处于STATUS_CONNECTING或STATUS_WAITING状态时通过nanosleep(100ms)/Sleep(100)主动让出 CPUclient/pub_client.c 与 client/pub_client.c在STATUS_CONNACK_RECVD状态下逐行读取 stdin 并调用my_publish()发布client/pub_client.cEOF 时依据是否仍有在途消息决定直接断开或进入STATUS_WAITING等待确认client/pub_client.c。该修复对管道类用法尤其重要例如tail -f /var/log/x | mosquitto_pub -l -t topic这类持续输入场景慢网络下不会再把 CPU 烧满。升级建议与验证清单综合本次发布内容升级与验证可按如下清单推进安全优先无论使用 1.5 还是 1.6 分支都应升级至对应修复版本1.5.10 / 1.6.12特别是启用了持久化并存在大量非干净会话客户端的部署队列参数审视检查max_queued_messages与max_queued_bytes的当前取值在内存允许的前提下避免过小的队列上限触发频繁丢弃并考虑双上限组合脚本返回值将客户端命令的退出码纳入检查逻辑CONNACK 失败现在会返回非零退出码可用于自动化告警裁剪编译若使用WITH_BRIDGEno/WITH_TLSno构建升级后可确认警告已消除回归验证针对mosquitto_pub -l的管道输入场景做一次慢网络或限速测试确认 CPU 占用不再持续高企。以上各项改进均可在当前仓库中溯源验证安全修复相关的队列机制见 src/database.c 与 src/handle_publish.c配置项说明见 mosquitto.conf构建开关见 config.mk客户端行为见 client/pub_client.c 与 client/sub_client.c发布记录见 ChangeLog.txt。赞分享物联网消息队列后端网络/通信【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mo/mosquitto点击查看免费下载相关推荐Eclipse Mosquitto 1.6.12 发布详解QoS 2 消息内存泄漏修复与客户端退出码修正Eclipse Mosquitto 1.6.12 发布详解QoS 2 消息内存泄漏修复与客户端退出码修正 导读 本文围绕 Eclipse Mosquitto后端消息队列消息路由10分钟装好一个ESPHome漏水报警器零门槛新手实操指南10分钟装好一个ESPHome漏水报警器零门槛新手实操指南 凌晨两点洗衣机排水管在渗水等你早上发现地板已经泡了半小时。用 ESPHome一个写配置文件物联网消息队列后端网络/通信Eclipse Mosquitto 0.5/0.5.1 版本解析内存化持久存储、自动保存与命令行客户端工具Eclipse Mosquitto 0.5/0.5.1 版本解析内存化持久存储、自动保存与命令行客户端工具 本文基于仓库内 0.5.1 发布公告 https:物联网消息队列后端网络/通信上一篇Qwen3.5-35B-A3B-MXFP4模型深度解析AMD MI300平台上的高效量化方案下一篇TypeGraphQL类型文档API以编程方式访问文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑