ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Mosquitto 1.0.2 版本解析:$SYS 持久化缺陷修复与配套工具链改进

Mosquitto 1.0.2 版本解析:$SYS 持久化缺陷修复与配套工具链改进 后端消息队列消息路由【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mos/mosquitto点击查看免费下载本篇技术指南围绕 Eclipse Mosquitto 1.0.2 版本发布公告展开逐一拆解本次 bugfix 版本修复的五大问题持久化场景下$SYS/#订阅导致数据库缺失消息、部分系统上的线程问题、SSL 测试用例的 socket 泄漏、CMake 安装缺失pskfile.example示例文件以及db_dump参数打印异常。读完本文你将理解 Mosquitto 持久化机制中$SYS主题消息的特殊处理逻辑并掌握db_dump工具的使用方法与输出格式。版本概览一次聚焦稳定性与工程细节的 bugfix 发布Mosquitto 1.0.2 发布于 2012 年 8 月 19 日发布公告见 www/posts/2012/08/version-1-0-2-released.md性质是一次典型的 bugfix release——不引入新功能而是集中修复 broker、客户端库、测试脚本与构建脚本中的缺陷。发布公告按Broker、Library、Tests、Build scripts、Other五个类别组织变更内容这种分类方式在仓库根目录的 ChangeLog.txt 中得到完整对应其中 1.0.2 条目标注日期 20120919与公告逐条一致可用于交叉核对。值得说明的是当前仓库已迭代至更晚版本持久化数据库格式已升级为 v6见 src/persist.h因此下文涉及的源码均以当前仓库实现为准用于阐释这些修复背后的设计意图与机制。Broker 修复$SYS/# 订阅导致持久化数据库消息缺失本次修复中最具技术含量的是 Broker 问题如果 broker 开启了持久化persistence一个持久客户端durable client订阅了$SYS/#主题并且在其消息队列中还有消息时重启 broker则持久化数据库会出现消息缺失导致 broker 无法正常重启。问题根因$SYS 消息的特殊持久化策略要理解这个 bug需要先了解 Mosquitto 对$SYS主题消息的特殊处理。$SYS主题树是 broker 内部自生成的系统状态主题如$SYS/broker/uptime、$SYS/broker/connection//state等其产生与持久化逻辑都不同于普通业务消息。当前仓库的 src/persist_write.c 中persist__message_store_save()函数揭示了这套策略的核心规则if(!strncmp(base_msg-data.topic, $SYS, 4)){ if(base_msg-ref_count 1 base_msg-dest_id_count 0){ /* $SYS messages that are only retained shouldnt be persisted. */ continue; } /* Dont save $SYS messages as retained otherwise they can give * misleading information when reloaded. They should still be saved * because a disconnected durable client may have them in their * queue. */ chunk.F.retain 0; }这段代码体现了三个关键设计决策纯 retained 的$SYS消息不写入持久化数据库——$SYS主题是 broker 运行时状态重启后会重新生成将其固化为 retained 消息反而会给出误导性信息但被持久客户端队列引用的$SYS消息必须保存——因为这些消息是投递给离线持久客户端的承诺丢了就无法恢复保存时强制清除 retain 标记避免重启后$SYS消息以 retained 身份残留。同理在persist__client_messages_save()中src/persist_write.c写客户端队列消息时会再次检查if(!strncmp(cmsg-base_msg-data.topic, $SYS, 4) cmsg-base_msg-ref_count 1 cmsg-base_msg-dest_id_count 0){ /* This $SYS message wont have been persisted, so we cant persist * this client message. */ cmsg cmsg-next; continue; }1.0.2 修复的意义1.0.2 修复的正是上述两处检查在旧版本中的不一致当持久客户端同时满足订阅$SYS/#队列中有$SYS消息broker 重启三个条件时旧逻辑会把队列中的$SYS消息与 base message 存储一并漏写导致持久化数据库中的消息引用store_id悬空broker 重启解析数据库时无法正确恢复客户端队列最终表现为无法正常重启。从当前实现回看正确做法是只有无队列引用且仅 retained的$SYS消息才被排除凡是 durable client 队列仍引用的$SYS消息都必须随数据库落盘。这要求消息存储DB_CHUNK_BASE_MSG与客户端消息DB_CHUNK_CLIENT_MSG两类 chunk 的写入逻辑保持一致的引用计数判断任何一处的遗漏都会造成数据不一致。配置触发条件该 bug 的复现需要持久化功能开启相关配置项在 src/conf.c 中解析persistence true开启 broker 持久化persistence_file持久化数据库文件名默认mosquitto.dbpersistence_location持久化文件所在目录autosave_interval自动保存间隔默认 1800秒见 src/conf.cpersistent_client_expiration持久客户端会话过期时长默认 0不过期。其中autosave_interval的触发逻辑在 src/loop.c当persistence开启且autosave_interval非零时主循环会累计persistence_changes达到阈值或超过时间间隔即触发数据库落盘。Library 修复部分系统上的线程问题发布公告中 Library 部分仅一条修复某些系统上的线程问题。虽然公告未给出细节但从 Mosquitto 客户端库的架构可以推断libmosquitto 同时支持多线程回环mosquitto_loop_start()与单线程回环mosquitto_loop()两种模式二者会共享网络与消息队列结构任何互斥锁初始化顺序、临界区保护或条件变量使用不当都会在特定平台尤其是线程调度行为不同的系统上表现出偶发崩溃或数据竞争。Tests 修复SSL 测试后的 socket 关闭1.0.2 修复了08-ssl-connect-no-auth-wrong-ca.py测试结束后未关闭 socket 的问题——该测试验证使用错误 CA 的 SSL 连接应当被拒绝若不关闭 socket泄漏的文件描述符会让后续测试用例出现干扰。当前仓库中该测试仍存在见 test/broker/08-ssl-connect-no-auth-wrong-ca.py。测试逻辑为启动配置了 CA 与证书的 broker客户端使用另一套 CAtest-alt-ca.crt发起 SSL 连接预期握手抛出ssl.SSLError并在finally块中确保ssock.close()sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) context ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafilef{ssl_dir}/test-alt-ca.crt) context.minimum_version ssl.TLSVersion.TLSv1_2 ssock context.wrap_socket(sock, server_hostnamelocalhost) ssock.settimeout(20) try: ssock.connect((localhost, port1)) except ssl.SSLError as err: if err.errno 1: pass finally: ssock.close()该用例注册在 test/broker/test.py 的测试清单中作为 broker SSL 连接测试序列的一环。try/except/finally结构正是 1.0.2 修复目标——无论握手成功与否socket 都必须被显式关闭避免影响后续测试。Build scripts 修复CMake 安装 pskfile.example1.0.2 修复了 CMake 构建体系未安装pskfile.example的问题对应 bug #1037504。此前只有 Makefile 构建体系在make install时安装该文件使用 CMake 构建的用户安装后找不到 PSK 示例配置文件。当前仓库中两种构建体系均已覆盖该文件的安装CMakeCMakeLists.txt 中custom_install(FILES aclfile.example pskfile.example pwfile.example DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/mosquitto)MakefileMakefile 中$(INSTALL) -m 644 pskfile.example ${DESTDIR}/etc/mosquitto/pskfile.example。pskfile.example的内容非常简单演示了 TLS-PSK预共享密钥认证的明文密钥文件格式——每行一条身份:密钥记录id:deadbeef easy:12345该文件配合 broker 配置中的psk_file选项使用用于为使用 PSK 的客户端提供预共享密钥。Other 修复db_dump 参数打印 message store 与 sub chunks发布公告最后一条修复了db_dump工具的参数打印问题——具体是打印 message storebase message与订阅subscriptionchunk 时的参数传递错误导致输出信息不正确。db_dump是 Mosquitto 附带的持久化数据库离线查看工具源码位于 apps/db_dump/db_dump.c。其用法apps/db_dump/db_dump.cUsage: db_dump [--stats | --client-stats | --json] mosquitto db filename直接指定数据库文件逐 chunk 打印全部内容--stats仅统计各类 chunk 的数量CFG / BASE_MSG / CLIENT_MSG / RETAIN / SUB / CLIENT--client-stats按客户端统计订阅数与队列消息数--json以 JSON 形式输出。持久化数据库由 15 字节魔数magic CRC 版本号 若干 chunk 组成chunk 类型定义于 src/persist.hDB_CHUNK_CFG 1 DB_CHUNK_BASE_MSG 2 DB_CHUNK_CLIENT_MSG 3 DB_CHUNK_RETAIN 4 DB_CHUNK_SUB 5 DB_CHUNK_CLIENT 6db_dump的主循环即按这些类型分发处理apps/db_dump/db_dump.c遇到未知 chunk 类型会跳过并给出警告。1.0.2 修复所涉及的输出逻辑位于 apps/db_dump/print.cprint__base_msg()apps/db_dump/print.c打印 Store ID、源端口、源 MID、主题、QoS、Retain、Payload 长度、过期时间并对小于 256 字节且通过 UTF-8 校验的 payload 做文本输出随后打印 MQTT v5 属性如 payload format、content type、user property 等print__sub()apps/db_dump/print.c打印客户端 ID、订阅主题、QoS、订阅标识符与订阅选项。正确传入 chunk 结构指针而非其他类型是这两处输出准确性的前提正是 1.0.2 修复的参数问题。这些示例输出也可作为运维排查持久化数据库内容是否正确的对照依据。总结与验证建议Mosquitto 1.0.2 虽是一次小版本 bugfix 发布但其修复内容覆盖了从核心 broker 持久化一致性、客户端库线程安全到测试脚本资源管理、构建安装完整性与工具输出正确性的全链路体现了开源 MQTT broker 工程化维护的细致程度。如果你想在本地验证本文提到的机制可以按以下路径操作核对版本记录阅读 ChangeLog.txt 中 1.0.2 条目与发布公告逐条比对理解 $SYS 持久化策略阅读 src/persist_write.c重点观察$SYS前缀判断与ref_count/dest_id_count的配合演练 db_dump使用persistence true配置运行 broker 一段时间后停止对生成的mosquitto.db执行db_dump --stats db文件与db_dump db文件观察各类 chunk 的输出结构当前版本数据库格式为 v6查看 PSK 示例参考仓库根目录的 pskfile.example 与aclfile.example、pwfile.example三个示例文件理解 broker 配置文件中对应选项的输入格式。需要特别提醒的是$SYS主题消息的持久化属于 broker 内部机制1.0.2 之后的版本在此基础上持续演进当前仓库的 src/persist_write.c 已包含 MQTT v5 属性与消息过期时间等新逻辑但其纯 retained 的 $SYS 消息不落盘、被持久客户端队列引用的必须落盘且清除 retain的核心原则一脉相承。赞分享后端消息队列消息路由【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mos/mosquitto点击查看免费下载相关推荐Mosquitto 1.5.7 发布说明详解Broker 配置、持久化与主题匹配的缺陷修复Mosquitto 1.5.7 发布说明详解Broker 配置、持久化与主题匹配的缺陷修复 Mosquitto 1.5.7 是一个纯缺陷修复bugfix版后端消息队列消息路由Eclipse Mosquitto 1.6.8 版本解析一次覆盖 Broker、客户端库与工具链的全面缺陷修复Eclipse Mosquitto 1.6.8 版本解析一次覆盖 Broker、客户端库与工具链的全面缺陷修复 Mosquitto 1.6.8 是 Eclip后端消息队列消息路由Eclipse Mosquitto 2.0.5 版本发布解析Broker 关键缺陷修复、桥接连接与构建改进全览Eclipse Mosquitto 2.0.5 版本发布解析Broker 关键缺陷修复、桥接连接与构建改进全览 本文基于 Mosquitto 官方 2.0.5后端消息队列消息路由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表