Apache DolphinScheduler Alert SPI 告警插件架构与开发实践

发布时间:2026/11/9 1:55:25

Apache DolphinScheduler Alert SPI 告警插件架构与开发实践 Apache DolphinScheduler Alert SPI 告警插件架构与开发实践【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler本文以 Apache DolphinScheduler 的告警插件扩展机制Alert SPI为主线系统讲解AlertChannelFactory扩展接口、插件参数体系、基于PrioritySPI的插件加载与优先级仲裁机制并结合仓库中 Email 等内置插件的真实源码给出从接口设计到插件落地的完整参考路径。读完本文你将能够独立实现一个自定义告警渠道插件并理解 DolphinScheduler 如何做到“插件开发者只写业务逻辑加载、路由、前端表单生成全部由内核完成”。一、微内核 插件架构Alert SPI 的设计出发点DolphinScheduler 正在向微内核microkernel 插件架构演进。任务执行、资源存储、注册中心乃至告警通道这些核心能力都被设计为扩展点extension point目标是利用 SPI 提升系统自身灵活性与可扩展性。关于告警相关代码官方扩展文档明确指向dolphinscheduler-alert-api模块该模块定义了告警插件的扩展接口和基础代码任何需要实现告警插件化的工作都建议先阅读这个模块的代码。这一设计带来一个非常实际的开发体验插件加载、实例化、按名称路由等底层逻辑全部由内核实现插件开发者只需要关注org.apache.dolphinscheduler.alert.api.AlertChannelFactory一个接口的扩展。也就是说你不需要理解 ServiceLoader 的细节、不需要处理插件之间的冲突只要实现接口、声明好参数内核就会把你写的插件挂载进告警体系。官方同时给出了扩展稳定性承诺扩展接口除新增外几乎不做变更除非出现重大结构调整或不兼容的大版本升级因此基于当前接口编写的插件可以长期复用。二、Alert SPI 五大核心类dolphinscheduler-alert-api模块是 ALERT SPI 的核心全部关键类位于 org.apache.dolphinscheduler.alert.api 包下。逐个看2.1 AlertChannelFactory插件工厂接口所有告警插件都必须实现 AlertChannelFactory 接口。该接口用于定义插件名称与所需参数create方法用于创建具体的告警插件实例。源码中它只有三个抽象方法和一个默认方法public interface AlertChannelFactory extends PrioritySPI { /** 返回告警渠道的名称 */ String name(); /** 创建告警渠道实例 */ AlertChannel create(); /** 返回该插件需要在 Web UI 上展示的可配置参数 */ ListPluginParams params(); default SPIIdentify getIdentify() { return SPIIdentify.builder().name(name()).build(); } }三个方法各管一事方法职责name()插件在系统中的唯一标识名称如Email上层系统按名称路由到对应插件params()返回插件参数定义列表内核据此转换为 JSON驱动前端动态渲染配置表单create()每次需要发送告警时内核调用它拿到一个AlertChannel实例2.2 AlertChannel发送告警的唯一入口AlertChannel 是告警插件本体接口只有一个方法public interface AlertChannel { AlertResult process(AlertInfo info); }上层告警系统调用process方法并通过其返回的AlertResult获得告警结果。插件的全部业务逻辑构造请求、调用 API、落盘脚本等都收敛在这一个方法内。2.3 AlertInfo / AlertData进参上层系统调用插件实例时会构造一个 AlertInfo 传入process方法。从源码看它包含三部分public class AlertInfo { private MapString, String alertParams; // 前端为插件实例填写的参数 private AlertData alertData; // 告警内容本体 private int alertPluginInstanceId; // 告警插件实例 ID }其中 AlertData 承载告警内容包括id告警记录 IDtitle告警标题content告警正文HTML 文本log告警关联日志alertType告警类型编码对应AlertType#code。2.4 AlertResult出参AlertResult 是插件的返回信息只有success与message两个字段并提供两个静态工厂方法插件实现中直接复用即可public static AlertResult success() { return new AlertResult(true, null); } public static AlertResult fail(String message) { return new AlertResult(false, message); }三、插件参数体系用 Java 代码“画”出前端表单这是 Alert SPI 最巧妙的设计。DolphinScheduler 采用了前端组件库form-create其能力基于 JSON 动态生成前端 UI 组件。插件开发者完全不需要关心前端只要把插件参数用org.apache.dolphinscheduler.spi.params包下的参数类定义好内核会把这些参数统一转换为 JSON前端据此渲染出表单。开发者只关心前后端之间交换的数据。3.1 参数类的演进从文档描述到当前源码原文档指出该包当时封装了RadioParam单选、TextParam文本、PasswordParam密码三类参数基类为AbsPluginParams。对照当前仓库源码 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/params参数体系已扩展为基类 PluginParams即文档中的AbsPluginParams演进而来配套DataType、FormType、ParamsOptions、ParamsProps、Validate等基础定义input包InputParam文本输入可通过setType(password)变体为密码框对应原文档的 TextParam / PasswordParam 能力、InputNumberParam数字输入radio包RadioParam单选按钮select包SelectParam下拉选择PluginParamsTransfer负责参数列表与 JSON 之间的转换。每个 DS 告警插件都在AlertChannelFactory的实现中返回一个PluginParams列表这保证了“接口声明”与“表单渲染”的一致性。3.2 实例拆解Email 插件的 params() 实现以 EmailAlertChannelFactory 为例它的params()方法定义了 12 个前端可见参数Override public ListPluginParams params() { ListPluginParams paramsList new ArrayList(); // 收件人必填附国际化占位提示 InputParam receivesParam InputParam .newBuilder(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS) .setPlaceholder(JSONUtils.toJsonString(AlertInputTips.getAllMsg(AlertInputTips.RECEIVERS))) .addValidate(Validate.newBuilder().setRequired(true).build()) .build(); // SMTP 端口数字类型默认 25 InputNumberParam mailSmtpPort InputNumberParam .newBuilder(MailParamsConstants.NAME_MAIL_SMTP_PORT, MailParamsConstants.MAIL_SMTP_PORT) .setValue(25) .addValidate(Validate.newBuilder() .setRequired(true) .setType(DataType.NUMBER.getDataType()).build()) .build(); // SMTP 鉴权开关单选 Yes/No默认 true RadioParam enableSmtpAuth RadioParam .newBuilder(MailParamsConstants.NAME_MAIL_SMTP_AUTH, MailParamsConstants.MAIL_SMTP_AUTH) .addParamsOptions(new ParamsOptions(STRING_YES, STRING_TRUE, false)) .addParamsOptions(new ParamsOptions(STRING_NO, STRING_FALSE, false)) .setValue(STRING_TRUE) .addValidate(Validate.newBuilder().setRequired(true).build()) .build(); // 密码通过 setType(password) 复用文本输入组件 InputParam mailPassword InputParam .newBuilder(MailParamsConstants.NAME_MAIL_PASSWD, MailParamsConstants.MAIL_PASSWD) .setPlaceholder(JSONUtils.toJsonString(AlertInputTips.getAllMsg(AlertInputTips.PASSWORD))) .setType(password) .build(); // 展示形态Table / Text / Attachment / Table_Attachment 四选一 RadioParam showType RadioParam .newBuilder(AlertConstants.NAME_SHOW_TYPE, AlertConstants.SHOW_TYPE) .addParamsOptions(new ParamsOptions(ShowType.TABLE.getDescp(), ShowType.TABLE.getDescp(), false)) .addParamsOptions(new ParamsOptions(ShowType.TEXT.getDescp(), ShowType.TEXT.getDescp(), false)) // ... 其余选项 .setValue(ShowType.TABLE.getDescp()) .addValidate(Validate.newBuilder().setRequired(true).build()) .build(); paramsList.add(receivesParam); // ... 依次加入其余参数 return paramsList; }从中可以提炼出参数定义的通用套路Builder 模式InputParam.newBuilder(paramKey, paramLabel)第一参数是提交到后端的 key第二参数是表单标签默认值setValue(...)指定初始值校验addValidate(Validate.newBuilder().setRequired(true).build())标记必填数字类型用DataType.NUMBER国际化提示setPlaceholder传入AlertInputTips中的多语言提示 JSON单选选项RadioParam通过多个ParamsOptions展示文案、提交值、是否默认描述选项。这些参数定义会被内核转换后交给前端 form-create最终在“告警组Alert Group”配置页动态生成表单用户填写后以MapString, String形式回流到AlertInfo.alertParams——这正是process(AlertInfo)里读取配置的来源。四、插件加载与优先级仲裁机制4.1 原生 Java SPI AutoServiceDolphinScheduler 使用原生 Java SPI做插件发现。插件侧的注册成本极低——以 Email 插件为例工厂类上只需一行注解AutoService(AlertChannelFactory.class) public final class EmailAlertChannelFactory implements AlertChannelFactory { ... }AutoService在编译期自动生成META-INF/services下的服务声明文件插件开发者无需手写服务注册文件。4.2 PrioritySPI同名插件的优先级仲裁AlertChannelFactory继承自 PrioritySPI。这意味着插件可以声明优先级当两个插件同名时可通过重写getIdentify方法自定义SPIIdentify中的优先级高优先级插件会被加载若两个插件同名且优先级相同服务在加载插件时会抛出IllegalArgumentException。PrioritySPI接口本身只声明了getIdentify()与基于优先级的compareTo。真正执行仲裁的是 PrioritySPIFactory其核心逻辑值得逐行看public PrioritySPIFactory(ClassT spiClass) { for (T t : ServiceLoader.load(spiClass)) { if (map.containsKey(t.getIdentify().getName())) { resolveConflict(t); } else { map.put(t.getIdentify().getName(), t); } } } private void resolveConflict(T newSPI) { SPIIdentify identify newSPI.getIdentify(); T oldSPI map.get(identify.getName()); if (newSPI.compareTo(oldSPI.getIdentify().getPriority()) 0) { throw new IllegalArgumentException( String.format(These two spi plugins has conflict identify name with the same priority: %s, %s, oldSPI.getIdentify(), newSPI.getIdentify())); } else if (newSPI.compareTo(oldSPI.getIdentify().getPriority()) 0) { log.info(The {} plugin has high priority, will override {}, newSPI.getIdentify(), oldSPI); map.put(identify.getName(), newSPI); } else { log.info(The low plugin {} will be skipped, newSPI); } }从源码结构看加载流程即ServiceLoader扫描所有实现了该接口的类 → 以getIdentify().getName()为键存入map→ 命中重名时进入resolveConflict优先级相同则直接抛异常快速失败新插件优先级更高则覆盖旧插件否则跳过。这种“快速失败 日志可追溯”的仲裁策略既允许团队内部覆盖官方插件同名更高优先级又能防止两个同名插件静默并存造成难以排查的歧义。AlertChannelFactory中的默认实现getIdentify()仅以name()构建SPIIdentify不显式设置优先级因此普通插件无需关心优先级只有需要覆盖同名插件时才重写它。五、模块结构API 与内置插件的分层告警 SPI 在仓库中对应两个 Maven 模块dolphinscheduler-alert-apiALERT SPI 核心模块定义插件扩展接口与基础代码本文第二节的五大类均在此扩展插件必须实现其中定义的AlertChannelFactory接口dolphinscheduler-alert-plugins内置插件聚合模块官方提供了一批开箱即用的告警渠道插件。上层调用方则是dolphinscheduler-alert-server告警服务它负责接收告警、查询告警组、按渠道类型加载对应插件并调用process发送。插件开发者面向的契约边界就是alert-api模块这正是“内核与插件解耦”的体现。六、内置告警插件一览原文档列举了 Email、DingTalk、EnterpriseWeChat、Script、SMS、FeiShu、Slack、PagerDuty、WebexTeams、Telegram、Http 等内置实现。对照当前仓库dolphinscheduler-alert-plugins目录下的实际模块内置插件清单为插件模块说明dolphinscheduler-alert-email邮件告警支持 SMTP 鉴权、TLS/SSL、表格/文本/附件等多种展示形态dolphinscheduler-alert-dingtalk钉钉群机器人告警dolphinscheduler-alert-wechat企业微信告警dolphinscheduler-alert-scriptShell 脚本告警内核把告警参数传给脚本你在脚本中实现任意告警逻辑是对接内部自建告警系统的通用方式dolphinscheduler-alert-feishu飞书告警dolphinscheduler-alert-slackSlack 告警dolphinscheduler-alert-pagerdutyPagerDuty 告警dolphinscheduler-alert-webexteamsWebexTeams 告警dolphinscheduler-alert-telegramTelegram 告警dolphinscheduler-alert-httpHTTP 告警由于大多数告警插件最终都是一次 HTTP 请求如果你的渠道尚未被支持可直接用 Http 插件实现自己的告警逻辑官方也欢迎把通用插件回馈社区dolphinscheduler-alert-aliyunVoice阿里云语音告警dolphinscheduler-alert-prometheusPrometheus 告警需要说明的是原文档中提及的 SMS短信渠道在当前仓库的插件目录中未找到对应模块实际可用渠道以仓库目录为准。此外dolphinscheduler-alert-all作为聚合模块可在打包时一次性引入全部内置插件。内置插件都遵循同一套骨架例如 Email 插件由 EmailAlertChannelFactory定义名称与参数 EmailAlertChannelprocess中解析alertParams完成 SMTP 发送组成配套template包下的AlertTemplate/DefaultHTMLTemplate负责 HTML 邮件模板渲染exception包下的AlertEmailException统一错误语义——这套“Factory Channel 模板 异常”的组织方式可以直接套用到任何新插件上。七、开发自己的告警插件步骤清单综合上文开发一个自定义告警渠道插件的完整路径是新建模块在dolphinscheduler-alert-plugins下创建插件模块依赖dolphinscheduler-alert-api实现工厂编写XxxAlertChannelFactory implements AlertChannelFactory实现name()唯一渠道名、params()用InputParam/RadioParam等定义前端表单参数可参照 EmailAlertChannelFactory、create()实现通道编写XxxAlertChannel implements AlertChannel在process(AlertInfo info)中从info.getAlertParams()读取用户配置、从info.getAlertData()读取告警内容发送成功后返回AlertResult.success()失败返回AlertResult.fail(message)注册服务工厂类加AutoService(AlertChannelFactory.class)注解编译期自动生成 SPI 注册文件如需覆盖同名插件重写getIdentify()提供更高优先级验证可参照 EmailAlertChannelFactoryTest 编写单测覆盖参数定义与工厂行为打包后在系统的“告警组”页面即可看到你的插件渠道并配置参数。整条链路中插件开发者只触碰两个接口和一组参数类服务发现、冲突仲裁、参数 JSON 化、前端表单渲染全部由内核PrioritySPIFactoryPluginParamsTransfer form-create承担。这种把复杂度压在扩展点之下的设计也是 DolphinScheduler 整个 SPI 体系任务、数据源、注册中心、告警共用的模式——读懂了 Alert SPI再去看 task.md、datasource.md、registry.md 等其它扩展点的文档基本可以触类旁通。【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/8 23:15:43

Python多线程批量检测URL状态码实战指南

简介:这是一份面向Web开发、运维及SEO工程师的Python多线程实战源码包,聚焦批量检测海量URL HTTP状态码这一高频运维需求,适用于网站健康巡检、死链清理、爬虫预检等场景。资源共42个文件,含8个DLL(依赖库)…

2026/11/9 4:05:46

Python高阶开发:设计模式、架构与工程化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/9 1:47:49

GKE Golden Path:生产级 Autopilot 集群的推荐配置实践指南

GKE Golden Path:生产级 Autopilot 集群的推荐配置实践指南 【免费下载链接】skills Agent Skills for Google products and technologies 项目地址: https://gitcode.com/GitHub_Trending/skills29/skills GKE Golden Path(黄金路径)…

2026/11/9 11:25:12

杭州特种工找工作报名避坑良心建议

杭州特种工找工作报名避坑良心建议 不知道去哪报名怕被中介坑?杭州特种工找工作,报名流程复杂、培训机构鱼龙混杂,很多人都踩过坑。今天这条内容,就从杭州本地角度出发,结合郑州劳务班组负责人的实际经验,给你一套 良心建议…

2026/11/9 11:25:12

杭州特种工找工作上岗必备怎么准备实操考试

杭州特种工找工作上岗必备怎么准备实操考试 实操考试心里没底怕挂科?你不是一个人。现在杭州特种工找工作越来越依赖【上岗必备】的特种作业证,但很多人在准备考试时,总担心自己能不能通过。尤其对于刚入行或者想转行的你来说,这不仅是证书的问题,更是关…

2026/11/9 11:25:12

杭州特种工找工作证怎么转异地 上岗必备全攻略

杭州特种工找工作证怎么转异地 上岗必备全攻略 之前考的证在外省能不能转过来?这个问法我听得太多了。我是干了10年特种作业相关工作的,从报名、考试到复审,每一步都踩过坑、吃过亏。今天就用一个真实的案例,带你们看看 杭州特种工找工作…

2026/11/9 11:25:12

株洲如何考取电工证2026河南最新政策怎么走

株洲如何考取电工证2026河南最新政策怎么走 不知道去哪报名怕被中介坑?株洲地区想考电工证的你,一定经历过这样的纠结。现在2026河南最新政策已经落地,报名流程、考试要求、证书查询等信息都有了明确的规定,但也正是这些信息,让不少人摸不着头脑…

2026/11/9 11:20:12

宜宾电工证培训条件全知道,外省证怎么转?在哪考最靠谱?

宜宾电工证培训条件全知道,外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到过不下十次,很多老电工、新学员都问过。现在宜宾的电工证培训条件和政策越来越规范,但 外省证能不能转 ,关键在于 在哪考…

2026/11/9 0:37:55

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/9 0:03:09

建设厅的特种工有哪些含金量高?别交完钱考不过

建设厅的特种工有哪些含金量高?别交完钱考不过 怕考不过白交培训费?别急,先搞清楚建设厅的特种工有哪些含金量高的证,再决定是不是值得投入时间和金钱。 建设厅的特种工证是建筑行业里最基础、也最实用的证书之一,涉及多个作业类别,每种证的 含金量…

2026/11/9 0:03:09

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱 怕考不过白交培训费?荆门市电工证报名前必须知道这些避坑指南。别看网上一堆培训机构广告,真要报个电工证,很多人被坑得一塌糊涂。特别是那些打着“包过”旗号的,最后不是考试不过,就是证不是全国通…

2026/11/9 0:03:09

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑 不知道去哪报名怕被中介坑?你不是一个人。现在特种作业证报名渠道五花八门,从线下培训机构到线上代理,真假难辨。尤其是像高空电工作业这类高风险、高门槛的作业类型,证书含金量和考试通过率直接影响你…

2026/11/9 6:30:27

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑