后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载本文围绕 EMQX 仓库中的变更记录 changes/ee/fix-18337.en.md 展开深入解析“插件启动必须晚于全部 EMQX 核心应用”这一启动时序机制的来龙去脉修复前插件在节点重启后为何会启动失败、修复后启动顺序如何被重新编排以及插件开发者可以如何利用新的applications依赖声明能力。读完本文你将理解 EMQX 节点引导boot阶段的应用启动管线掌握插件声明任意 EMQX 应用为依赖的正确姿势并了解这一行为在测试中是如何被验证的。变更背景修复前的启动失败问题在 EMQX 中插件Plugin以独立的 OTP 应用形式随节点启动。插件包内的release.json会描述其包含的应用程序而每个插件应用的.app文件或 Elixir 插件的mix.exs中的applications列表则声明了它依赖哪些应用。修复之前插件的启动时机偏早插件在节点引导阶段被启动时EMQX 的部分核心应用可能尚未启动完毕。如果一个插件在其applications列表中声明了一个在启动序列中排位靠后的应用——变更记录中明确以emqx_management为例——那么当节点重启node restart时该插件会因为所依赖的应用尚未运行而启动失败进而影响整个节点的插件体系。这正是 changes/ee/fix-18337.en.md 所记录的核心问题该变更同时被收录进 changes/6.2.3.en.md 的 6.2.3 版本发布说明对应 GitHub PR #18337。修复方案把插件启动挪到全部 EMQX 应用之后修复的核心思路非常直接先等所有 EMQX 应用启动完成再启动插件。这样插件在applications列表中声明任何 EMQX 应用都是安全的因为启动插件时这些应用必然已经处于运行状态。这一时序安排的落地点在节点引导的核心模块 apps/emqx_machine/src/emqx_machine_boot.erl 的ensure_apps_started/0函数中。从源码结构看该函数按如下顺序执行调用emqx_node_readiness:mark_not_ready()将节点标记为“未就绪”拒绝新的 MQTT 连接通过lists:foreach(fun start_one_app/1, sorted_reboot_apps())按依赖排序逐个启动所有 EMQX 核心应用在全部 EMQX 应用启动之后才调用emqx_plugins:ensure_started()启动所有已配置启用的插件最后调用emqx_node_readiness:mark_ready()将节点标记为就绪恢复接受连接。源码中的注释明确说明了这一设计的意图Start plugin applications only after all EMQX applications are up, so a plugin may depend on any of them.同时代码注释还指出ensure_apps_started/0同时也是 ekka 集群加入/离开join/leave的回调因此在集群 join 之后插件也会随之重新启动见start_autocluster/0。之所以要在插件全部启动完成前拒绝 MQTT 连接注释也给出了理由防止客户端在插件钩子hooks注册之前就连接上来从而保证认证、授权等由插件提供的钩子从节点一就绪就生效。这与 apps/emqx/src/emqx_node_readiness.erl 中“就绪状态由emqx_machine_boot:ensure_apps_started/0清除并恢复”的机制相互印证。插件应用自身的引导分工值得注意的是插件应用emqx_plugins自身的application回调并不负责启动业务插件而只负责基础设施。查看 apps/emqx_plugins/src/emqx_plugins_app.erl 的start/2启动插件监督树emqx_plugins_sup调用emqx_plugins:ensure_installed()安装解包并配置所有已配置的插件记录未配置的插件包日志注册配置更新处理器与 CLI 命令。源码注释明确写道真正的“插件应用启动”由emqx_machine_boot:ensure_apps_started/0在全部 EMQX 应用就绪之后统一触发“Plugin applications are started byemqx_machine_boot:ensure_apps_started/0after all EMQX applications are up”。也就是说emqx_plugins应用本身是 EMQX 应用列表中的一员但它所管理的第三方插件被刻意排到了整个启动管线的末尾。插件应用依赖声明与启动实现的细节声明任意 EMQX 应用为依赖修复之后插件在声明依赖时不再需要顾虑目标应用的启动顺序。插件包的release.json会列出其rel_apps而插件应用自身的依赖关系由.app文件或mix.exs中的applications字段决定。现在插件可以在该列表中放心声明诸如emqx_management这类启动靠后的应用因为插件启动时它们一定已经运行。在 apps/emqx_plugins/src/emqx_plugins_apps.erl 的注释中同样记录了这条约束的放宽During node boot, plugin apps are started after all EMQX applications (tail ofemqx_machine_boot:ensure_apps_started/0), so a plugin may declare any EMQX application as a dependency.启动实现ensure_all_started与超时保护插件的每个应用通过application:ensure_all_started/2启动见emqx_plugins_apps:start_app/1调用被包裹在run_with_timeout中超时阈值为10 秒启动成功时记录started_plugin_apps调试日志启动失败时返回包含app、reason的详细错误并附带not_running_deps字段——即在超时或失败时刻仍未运行的依赖应用列表方便定位问题如果发生超时错误信息中的hint会明确提示插件声明的每一个依赖应用mix 构建插件对应mix.exs中的声明都必须属于 EMQX release或随插件包一起打包。not_running_deps/1的实现会读取该应用的applications键与当前running_apps()求差集从而精确报告缺失的运行中依赖。消除自依赖避免启动死锁emqx_plugins_apps.erl中还实现了一个防御性细节drop_self_dep/1。如果插件的应用在applications中声明了对emqx_plugins自身的依赖加载应用规格时会自动将其剔除并记录一条 hint 日志。注释说明这是因为emqx_plugins在插件启动时必然已经在运行该声明属于冗余依赖剔除它可以让旧版本打包、在依赖关系上“死锁”的插件包在引导阶段继续正常工作。插件生命周期 API与引导路径的关系在 apps/emqx_plugins/src/emqx_plugins.erl 中ensure_started/0负责“启动所有已配置插件”它正是emqx_machine_boot:ensure_apps_started/0在引导末尾调用的入口。其内部行为包括读取已配置插件列表并归一化启用的版本对每个enable : true的插件执行do_ensure_started/1其中会依次校验无其他版本激活、安装插件包、读取release.json元数据、解析并校验启动配置最后调用emqx_plugins_apps:start/1单个插件启动失败不会抛出异常中断引导而是收集为{NameVsn, Reason}列表返回并记录日志保证一个坏插件不会拖垮整个节点启动对enable : false的插件仅记录调试日志跳过启动。ensure_stopped/0则是节点停止stop_apps/0时反向停止全部插件的入口两者配合构成了引导与关闭的完整闭环。测试验证引导路径与集群 join 周期该启动时序修复在 apps/emqx_plugins/test/emqx_plugins_SUITE.erl 中有专门的测试用例覆盖。其中t_boot_start_tolerates_broken_plugin用例的文档注释直接点出了这条修复后的启动路径ensure_started/0runs on the boot path (tail ofemqx_machine_boot:ensure_apps_started/0).该用例验证了三件事在配置中同时放入一个损坏的插件missing_plugin-1.0.0和一个正常插件时ensure_started/0返回ok且正常插件仍能启动——坏插件被“收集并记录”而非“抛出”不会导致节点引导失败ensure_started/0在插件已运行的情况下重复调用是安全的幂等操作模拟集群 join 周期先ensure_stopped/0停止插件再重新ensure_started/0插件可以顺利经历停止与重启验证了ensure_apps_started/0作为集群 join/leave 回调时的可重入性。测试套件中还有大量围绕插件安装、位置before/behind、重启与配置校验的用例可以作为进一步研读插件生命周期行为的入口。对插件开发者的实际影响这条变更对 EMQX 插件开发者意味着以下几点放宽依赖声明限制插件在applicationsErlang或mix.exsElixir中声明任何 EMQX 应用如emqx_management、emqx_rule_engine等作为依赖都是被支持的前提是该应用属于当前 EMQX release 或随插件包打包无需自行处理启动顺序不要在插件内部自行“等待”某个 EMQX 应用引导管线已经保证插件启动时所有 EMQX 应用都已就绪关注启动失败诊断信息若插件启动失败可在日志中查看not_running_deps与 hint 提示快速定位是依赖缺失还是依赖未打包利用 CLI 调整启动位置apps/emqx_plugins/src/emqx_plugins_cli_utils.erl 中的emqx ctl plugins enable Name-Vsn [Position]支持front/rear/before/behind等位置参数用于在插件之间调整启动顺序这与“插件整体晚于核心应用”的时序约束并不冲突。总结changes/ee/fix-18337.en.md 记录的虽然只是一条简短变更但它修复的是一个影响插件在节点重启后能否正常启动的关键时序问题。修复通过 apps/emqx_machine/src/emqx_machine_boot.erl 将插件启动统一排到全部 EMQX 应用之后配以就绪状态门控、幂等启动、失败容忍、依赖缺失诊断与集群 join 周期适配最终让“插件可以声明任意 EMQX 应用为依赖”成为一项可靠且可验证的工程能力。对于 EMQX 插件开发者而言理解这条启动管线是写出健壮、可随节点稳定重启的插件的前提。赞分享后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载相关推荐EMQX 预安装插件在 Dashboard 启动后出现 Plugin Config Not Found 的修复解析EMQX 预安装插件在 Dashboard 启动后出现 Plugin Config Not Found 的修复解析 导读 本文围绕 EMQX 插件管理体系中一个后端物联网消息队列通信tmux-continuum 插件实现 Tmux 自动启动详解tmux continuum 插件实现 Tmux 自动启动详解 前言 对于经常使用终端工作的开发者来说Tmux 是一个不可或缺的工具。它可以帮助我们管理多个终开发工具3 分钟搞定AIRI 接入 BytePlusModelArk聊天模型配置指南3 分钟搞定AIRI 接入 BytePlusModelArk聊天模型配置指南 三步就能让 AIRI 的实时对话换上 BytePlusModelArk的AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染上一篇VJ-FILTER-BOT广播功能使用教程高效管理用户与群组消息下一篇突破图表导出瓶颈vue-echarts大型数据可视化的性能优化指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
垃圾识别分类系统实战:基于CNN与迁移学习的图像分类全流程指南 简介:面向高校人工智能、计算机相关专业学生,这份基于深度学习卷积神经网络的垃圾识别分类系统源码,是一套可直接用于课程设计或期末大作业的完整项目。项目已获导师指导并取得97分高分,涵盖从数据集准备、模型训练到分类预测的完… · 2026/9/24 19:23:13
Python轻量工作流引擎:5分钟跑通审批流实战指南 1. 为什么 Python 开发者需要一个轻量工作流引擎
1.1 从“审批流”这个场景说起 但凡做过企业内部系统的开发者,大概率都碰过审批流这块硬骨头。请假审批、报销审批、采购审批、合同会签,业务逻辑看起来简单——无非是“提交、逐级审批、通过或驳回”&a… · 2026/9/24 19:23:13
OpenRouter替代方案选型指南:本地化、国产云与自建协议栈深度对比 1. 这不是“换一个网站”那么简单:先搞懂OpenRouter到底在解决什么问题OpenRouter这个词最近半年在开发者、AI应用工程师和中小团队技术负责人圈子里出现频率陡增,但很多人点开官网第一反应是:“这不就是个API聚合平台?”——这种… · 2026/9/24 19:55:40
国产PLM选型指南:从需求梳理到实施落地的完整实践 1. 广州制造业为什么现在开始认真谈国产PLM1.1 先搞清楚PLM到底解决什么问题PLM全称Product Lifecycle Management,中文一般叫产品生命周期管理。我每次给广州企业做选型辅导,都会先花半小时把这件事讲透:它不是一个画图软件,也不… · 2026/9/24 19:55:24
从sqlplus到gsql:Shell脚本迁移GaussDB的完整改造指南 上个月接了一个数据库国产化迁移的评估任务,业务 SQL 的兼容性问题提前过了,语法层面基本没有大阻碍。真正让我头疼的是那几十个在生产环境跑了好多年的 Shell 脚本——清一色的 sqlplus 调用,输出格式、退出码判断、SPOOL 文件解析全是按 Or… · 2026/9/24 19:55:05
数据中心微网两阶段鲁棒规划:灵活性建模与复现实践 数据中心微网的规划问题,近两年在EI期刊里出现的频率越来越高,尤其是“两阶段鲁棒优化”这个方向。手里正好在复现一篇相关的论文,题目是“考虑灵活性的数据中心微网两阶段鲁棒规划方法”,折腾了差不多三周,把Matlab代… · 2026/9/24 19:55:05
离线百科、iPad副屏与高颜值Linux:三款开源工具盘活旧设备 最近身边总有人问我三件事:出门在外的车上想查点东西,偏偏手机没信号,有没有离线查资料的办法?家里那台旧iPad除了躺在床头刷视频,还能不能干点正经事?Linux是不是永远跟“黑乎乎的命令行”“丑到没朋友”绑… · 2026/9/24 19:55:05
Oracle数据库控制文件重建实战:从损坏到恢复的完整指南 1. 什么情况需要重建控制文件,而不是傻等数据文件救场控制文件这玩意儿,平时存在感极低,低到很多DBA入职两三年都可能没正眼瞧过它。但它一旦出事,整个数据库直接瘫痪,实例都起不来,连个讨价还价的余地都没… · 2026/9/24 19:55:05
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44