DolphinScheduler插件开发:自定义任务插件

DolphinScheduler插件开发:自定义任务插件

【免费下载链接】dolphinscheduler Dolphinscheduler是一个分布式调度系统,主要用于任务调度和流程编排。它的特点是易用性高、可扩展性强、性能稳定等。适用于任务调度和流程自动化场景。 【免费下载链接】dolphinscheduler 项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler

概述

Apache DolphinScheduler 是一个分布式易扩展的可视化DAG(Directed Acyclic Graph,有向无环图)工作流任务调度系统。其强大的插件化架构允许开发者轻松扩展自定义任务类型,满足各种业务场景需求。本文将深入探讨如何开发自定义任务插件,从架构设计到具体实现,提供完整的开发指南。

插件架构概览

DolphinScheduler 采用模块化的插件架构,核心组件包括:

mermaid

核心接口详解

1. TaskChannel 接口

TaskChannel 是插件入口点,负责创建任务实例和解析参数:

public interface TaskChannel {
    AbstractTask createTask(TaskExecutionContext taskRequest);
    AbstractParameters parseParameters(String taskParams);
}

2. AbstractTask 抽象类

所有任务插件必须继承 AbstractTask,实现核心生命周期方法:

public abstract class AbstractTask {
    public abstract void init();
    public abstract void handle(TaskCallBack taskCallBack) throws TaskException;
    public abstract void cancel() throws TaskException;
    public abstract AbstractParameters getParameters();
}

3. AbstractParameters 抽象类

参数类封装任务配置信息:

public abstract class AbstractParameters {
    public abstract boolean checkParameters();
    public abstract List<ResourceInfo> getResourceFilesList();
}

开发自定义任务插件:实战示例

步骤1:创建项目结构

my-custom-task-plugin/
├── src/main/java/org/apache/dolphinscheduler/plugin/task/custom/
│   ├── CustomTaskChannel.java
│   ├── CustomTask.java
│   ├── CustomParameters.java
│   └── CustomTaskExecutor.java
├── pom.xml
└── META-INF/services/org.apache.dolphinscheduler.spi.plugin.TaskPlugin

步骤2:实现参数类

@Getter
@Setter
public class CustomParameters extends AbstractParameters {
    private String scriptContent;
    private Integer timeout;
    private List<ResourceInfo> resourceList;
    private Map<String, String> environmentVariables;

    @Override
    public boolean checkParameters() {
        return scriptContent != null && !scriptContent.trim().isEmpty();
    }

    @Override
    public List<ResourceInfo> getResourceFilesList() {
        return resourceList;
    }
}

步骤3:实现任务通道

public class CustomTaskChannel implements TaskChannel {
    
    @Override
    public CustomTask createTask(TaskExecutionContext taskRequest) {
        return new CustomTask(taskRequest);
    }

    @Override
    public CustomParameters parseParameters(String taskParams) {
        return JSONUtils.parseObject(taskParams, CustomParameters.class);
    }
}

步骤4:实现任务逻辑

@Slf4j
public class CustomTask extends AbstractTask {
    
    private CustomParameters parameters;
    private final TaskExecutionContext context;
    private final CustomTaskExecutor executor;

    public CustomTask(TaskExecutionContext context) {
        super(context);
        this.context = context;
        this.executor = new CustomTaskExecutor();
    }

    @Override
    public void init() {
        parameters = JSONUtils.parseObject(context.getTaskParams(), CustomParameters.class);
        if (parameters == null || !parameters.checkParameters()) {
            throw new TaskException("Custom task parameters validation failed");
        }
        log.info("Custom task initialized with parameters: {}", parameters);
    }

    @Override
    public void handle(TaskCallBack callback) throws TaskException {
        try {
            // 执行自定义逻辑
            ExecutionResult result = executor.execute(
                parameters.getScriptContent(),
                parameters.getTimeout(),
                parameters.getEnvironmentVariables()
            );
            
            setExitStatusCode(result.getExitCode());
            setProcessId(result.getProcessId());
            
            // 处理输出参数
            processOutputParameters(result.getOutput());
            
        } catch (Exception e) {
            log.error("Custom task execution failed", e);
            setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
            throw new TaskException("Custom task execution error", e);
        }
    }

    @Override
    public void cancel() throws TaskException {
        executor.cancel();
    }

    @Override
    public AbstractParameters getParameters() {
        return parameters;
    }
    
    private void processOutputParameters(String output) {
        // 解析输出并设置参数
    }
}

步骤5:创建SPI配置文件

META-INF/services/org.apache.dolphinscheduler.spi.plugin.TaskPlugin 中注册插件:

org.apache.dolphinscheduler.plugin.task.custom.CustomTaskChannel

步骤6:配置Maven依赖

<dependencies>
    <dependency>
        <groupId>org.apache.dolphinscheduler</groupId>
        <artifactId>dolphinscheduler-task-api</artifactId>
        <version>${dolphinscheduler.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.dolphinscheduler</groupId>
        <artifactId>dolphinscheduler-common</artifactId>
        <version>${dolphinscheduler.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

插件部署与集成

部署方式

部署方式说明适用场景
独立JAR包将插件打包成JAR,放入插件目录开发测试环境
Maven依赖作为依赖集成到主项目生产环境
动态加载通过SPI机制动态加载热部署场景

配置示例

plugin.properties 中配置插件信息:

# 自定义任务插件配置
custom.task.plugin.name=CustomTask
custom.task.plugin.description=自定义任务执行插件
custom.task.plugin.version=1.0.0
custom.task.plugin.author=YourName

最佳实践与注意事项

1. 参数验证

@Override
public boolean checkParameters() {
    if (StringUtils.isBlank(scriptContent)) {
        return false;
    }
    if (timeout != null && timeout <= 0) {
        return false;
    }
    return true;
}

2. 异常处理

try {
    // 业务逻辑
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    log.error("Task interrupted", e);
    setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
    throw new TaskException("Task interrupted", e);
} catch (TimeoutException e) {
    log.warn("Task timeout", e);
    setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
    throw new TaskException("Task timeout", e);
} catch (Exception e) {
    log.error("Unexpected error", e);
    setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
    throw new TaskException("Unexpected error", e);
}

3. 资源管理

@Override
public List<ResourceInfo> getResourceFilesList() {
    List<ResourceInfo> resources = new ArrayList<>();
    if (resourceList != null) {
        resources.addAll(resourceList);
    }
    // 添加默认资源
    resources.add(new ResourceInfo("default-config.properties", "config"));
    return resources;
}

调试与测试

单元测试示例

@Test
public void testCustomTaskExecution() {
    CustomParameters parameters = new CustomParameters();
    parameters.setScriptContent("echo 'Hello World'");
    parameters.setTimeout(30);
    
    TaskExecutionContext context = new TaskExecutionContext();
    context.setTaskParams(JSONUtils.toJsonString(parameters));
    
    CustomTask task = new CustomTask(context);
    task.init();
    
    // 执行测试
    task.handle(new SimpleTaskCallBack());
    
    assertEquals(TaskConstants.EXIT_CODE_SUCCESS, task.getExitStatusCode());
}

集成测试流程

mermaid

性能优化建议

1. 连接池管理

public class ConnectionPoolManager {
    private static final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
    
    public static Connection getConnection(String dataSourceName) throws SQLException {
        DataSource dataSource = dataSourceMap.computeIfAbsent(dataSourceName, 
            key -> createDataSource(key));
        return dataSource.getConnection();
    }
}

2. 异步处理

@Override
public void handle(TaskCallBack callback) throws TaskException {
    CompletableFuture.runAsync(() -> {
        try {
            // 异步执行耗时操作
            executeAsyncLogic();
            callback.onSuccess();
        } catch (Exception e) {
            callback.onFailure(e);
        }
    });
}

常见问题排查

问题现象可能原因解决方案
插件加载失败SPI配置错误检查META-INF/services文件
参数解析异常JSON格式错误验证参数格式
任务执行超时资源不足或逻辑复杂优化代码或增加超时时间
内存泄漏资源未正确释放使用try-with-resources

总结

DolphinScheduler 的插件架构提供了强大的扩展能力,通过实现 TaskChannel、AbstractTask 和 AbstractParameters 三个核心接口,开发者可以轻松创建自定义任务插件。本文详细介绍了插件开发的完整流程,包括架构设计、代码实现、部署集成和性能优化等方面。

关键要点:

  • 遵循插件接口规范,确保兼容性
  • 完善的参数验证和异常处理机制
  • 合理的资源管理和性能优化
  • 全面的测试覆盖和问题排查方案

通过自定义任务插件,可以扩展 DolphinScheduler 的功能边界,满足各种复杂的业务场景需求,为企业的数据调度和流程自动化提供强有力的技术支持。

【免费下载链接】dolphinscheduler Dolphinscheduler是一个分布式调度系统,主要用于任务调度和流程编排。它的特点是易用性高、可扩展性强、性能稳定等。适用于任务调度和流程自动化场景。 【免费下载链接】dolphinscheduler 项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值