Apache DolphinScheduler 启动参数(Startup Parameter)完全指南:工作流级参数配置、传递规则与源码原理
【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler
导读
启动参数(Startup Parameter)是 Apache DolphinScheduler 中针对整个工作流的所有任务节点均生效的参数,在工作流每次启动/运行前于“启动参数”配置界面中临时设置,适合注入日期、批次号、环境标记等每次运行都可能变化的变量。本文以官方文档《启动参数》为核心骨架,完整讲解其作用域、配置步骤与一个「打印不同日期」的 Shell 任务实战样例,并结合当前仓库源码(dolphinscheduler-master、dolphinscheduler-api、dolphinscheduler-ui)深入剖析启动参数在 Master 端与全局参数合并、被局部参数引用、在任务实例日志中验证生效的底层原理。读完本文,你将掌握启动参数的正确使用姿势、与其他参数类型的优先级关系,以及它在前端界面和后端执行链中的完整生命周期。
什么是启动参数
在 DolphinScheduler 中,参数来源众多,而启动参数是唯一一种在“工作流启动页面”临时配置、并在当次运行中对所有任务节点全局生效的参数。它的特点如下:
- 作用域为整个工作流:与节点级“局部参数”不同,启动参数在任意一个任务节点(Shell、SQL、Python、Spark、Flink 等)中都可以通过变量名直接引用;
- 配置时机为“启动时”:无需修改工作流定义(DAG),每次运行前都可修改取值,天然适合“每次运行传不同日期/批次”的调度场景;
- 本质上是全局参数的一次性注入:文档明确指出“工作流会将启动参数加入全局参数中”,从源码实现看,它是在 Master 生成工作流实例时与工作流定义中的全局参数进行合并的(详见下文源码解析)。
提示:启动参数与保存工作流时定义的全局参数在作用域上一致(都是全工作流生效),区别在于全局参数固化在工作流定义中,而启动参数仅作用于当次启动。
使用方式
启动参数的配置非常简单,具体步骤如下:
- 在工作流启动前的参数设置界面(即“请设置启动参数/Please set the parameters before starting”弹窗)中,点击“启动参数(Startup Parameter)”下方的加号(+);
- 填写对应的参数名称(如
dt)和参数值(如$[yyyy-MM-dd]); - 选择相应的参数值类型(
IN表示输入型参数,OUT表示输出型参数,供下游任务引用); - 点击确定/Confirm,工作流即会将启动参数加入本次运行的全局参数中,随后工作流内的所有任务节点均可引用。
从仓库前端实现看,该弹窗由 dag-startup-param.tsx 组件承载,它同时展示了本次运行的运行类型(Run Type)、失败策略(Failure Strategy)、工作流优先级(Workflow Priority)、Worker 分组、租户(Tenant Code)、通知策略与告警组等信息;其中commandParam字段直接取自props.startupParam.commandParam的 JSON 解析结果,说明启动参数在底层是通过命令参数(commandParam)随运行命令一起传递的。
任务样例:打印不同天的日期
下面通过官方文档提供的完整样例,演示如何利用启动参数让同一个 Shell 任务在两次运行时输出不同日期的值。
创建 Shell 任务
在工作流画布中创建一个Shell 任务,并在脚本内容中输入:
echo ${dt}此时dt就是我们准备声明的启动参数。如下图所示,脚本编辑器中用红色框标注了echo ${dt}:
保存工作流,上线运行并设置启动参数
保存工作流并上线后,点击运行。在启动前的参数配置界面中,按上文方式添加启动参数:
- 参数名:
dt - 参数值:
$[yyyy-MM-dd](衍生内置参数,表示以当前日期为基准,格式为 yyyy-MM-dd,详见内置参数) - 类型:
IN
配置效果如下图所示:
注:这里定义的
dt参数可以被其它任一节点的局部参数引用。也就是说,下游节点的“自定义参数”在设置值时可以引用${dt},实现“启动参数决定整条链路取值”的效果。这正是参数优先级中「启动参数 > 局部参数」的具体体现,完整优先级关系见参数优先级:上游任务传递的参数 > 启动参数 > 本地参数 > 全局参数 > 项目级别参数 > 内置参数。
任务实例查看执行结果
启动工作流后,进入任务实例页面,找到该 Shell 任务,点击查看日志。可以看到日志中打印了经过解析后的实际命令:
echo 2022-12-27说明${dt}已被解析为2022-12-27(即运行当天日期),启动参数生效。日志界面如下图所示:
修改启动参数,再次执行
回到工作流页面,再次点击运行,将启动参数dt的值修改为$[yyyy-MM-dd-1d](即当前日期前一天的衍生内置参数写法,表示前一天):
再次查看任务实例执行结果
再次进入任务实例页面查看日志,此时输出的日期应为前一天的日期(样例中为2022-12-29):
echo 2022-12-29通过对比两次日志可知:同一个 Shell 任务脚本(echo ${dt})无需任何修改,仅改变启动参数的取值,即可输出不同的日期。这正是启动参数的核心价值——把“变化的部分”从工作流定义中剥离出来,交给每次启动时按需注入。
源码解析:Master 如何合并启动参数
前文提到“工作流会将启动参数加入全局参数中”,在仓库源码中可以得到精确印证。当用户从 UI 发起一次工作流启动后,会生成一条CommandType.START_PROCESS命令,由 Master 端的 RunWorkflowCommandHandler.java 处理。其中关键代码如下:
workflowInstance.setGlobalParams(mergeCommandParamsWithWorkflowParams(command, workflowDefinition));而合并逻辑mergeCommandParamsWithWorkflowParams的完整实现为(L121-L137):
private String mergeCommandParamsWithWorkflowParams(final Command command, final WorkflowDefinition workflowDefinition) { final List<Property> commandParams = Optional.ofNullable(JSONUtils.parseObject(command.getCommandParam(), ICommandParam.class)) .map(ICommandParam::getCommandParams) .orElse(null); final List<Property> globalParamsList = GlobalParameterUtils.deserializeGlobalParameter(workflowDefinition.getGlobalParams()); Map<String, Property> finalParams = new HashMap<>(); if (CollectionUtils.isNotEmpty(globalParamsList)) { globalParamsList.forEach(globalParam -> finalParams.put(globalParam.getProp(), globalParam)); } if (CollectionUtils.isNotEmpty(commandParams)) { commandParams.forEach(commandParam -> finalParams.put(commandParam.getProp(), commandParam)); } return JSONUtils.toJsonString(finalParams.values()); }这段源码揭示了几个重要的实现事实:
- 启动参数存于命令参数(commandParam)中:UI 配置的启动参数被封装进
ICommandParam.getCommandParams()(List<Property>结构),随启动命令一并下发; - 与全局参数合并:Master 会先反序列化工作流定义中的全局参数(
GlobalParameterUtils.deserializeGlobalParameter),再逐项放入启动参数; - 同名时启动参数覆盖全局参数:因为二者都放入同一个
Map<String, Property>,后放入的 commandParams 会覆盖 key 相同的全局参数(源码注释也明确写道 “If there are duplicate keys, the command params will override the workflow params”)。这与文档《参数优先级》中「启动参数 > 全局参数」的规则完全一致; - 合并结果写入工作流实例:合并后的 JSON 通过
workflowInstance.setGlobalParams(...)持久化到工作流实例的globalParams字段,随后由 TaskExecutionContextBuilder 在构建任务执行上下文时下发到各任务节点,从而保证“整个工作流的所有任务节点都可见”。
从代码结构看,Property即为参数的标准载体(包含prop参数名、value参数值、direct输入/输出方向等字段),任务执行时对${dt}这类变量进行占位符替换,最终生成上文中日志里看到的实际命令(如echo 2022-12-27)。
启动参数与其它参数的联动
启动参数并非孤立存在,它与 DolphinScheduler 的其他参数体系存在明确的引用与优先级关系:
- 被局部参数引用:任一节点的“自定义参数”设置值时可以直接引用
${dt},使节点级变量也随启动参数联动(见局部参数); - 优先级排序:当同名参数同时存在时,
上游任务传递的参数 > 启动参数 > 本地参数 > 全局参数 > 项目级别参数 > 内置参数,启动参数的优先级高于本地参数、全局参数、项目参数与内置参数,仅低于上游任务通过参数上下文(Parameter Context)传递的参数(见参数优先级); - 支持日期类衍生内置参数:参数值支持
$[...]形式的衍生内置参数,如$[yyyy-MM-dd]、$[yyyy-MM-dd-1d]、$[add_months(yyyyMMdd,N)]等,可在启动时灵活计算“今天、昨天、上周、上月”等时间基准(完整列表见内置参数); - 跨节点传递:借助参数上下文(Parameter Context),上游任务可把输出参数(OUT)传递给下游,与启动参数共同构建完整的数据流(见参数传递)。
适用前提与注意事项
- 仅对当次运行生效:启动参数随启动命令写入该次工作流实例,不修改工作流定义本身;下次运行如需新值需重新配置;
- 适用于手动运行、补数(Backfill)、定时触发等各类启动场景:所有入口启动的工作流都会走命令参数合并流程;
- 参数名不要与业务无关字符冲突:变量引用统一使用
${变量名}占位符语法,参数值中的$[...]表达式会在启动前被解析为具体值; - 优先级需牢记:当启动参数与全局参数、项目参数同名时,启动参数的取值优先,覆盖关系已在 Master 源码的合并逻辑中得到验证。
小结
启动参数是 DolphinScheduler 中连接“工作流定义”与“当次运行上下文”的桥�梁:在 UI 侧只需一次点击与填写,即可让整个工作流的全部节点共享一个运行时变量;在 Master 侧,它通过命令参数与全局参数合并,写入工作流实例后随任务执行上下文逐级下发。结合「打印不同日期」的完整样例,你已经掌握如何用启动参数实现同一工作流、不同运行结果的典型用法,也能在排查参数不生效问题时,沿着commandParam → mergeCommandParamsWithWorkflowParams → workflowInstance.globalParams → TaskExecutionContextBuilder这条链路快速定位问题所在。
【免费下载链接】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),仅供参考