Início Tecnologia A programação mestre de conchas com Dolphinscheduler e ProcessBuilder

A programação mestre de conchas com Dolphinscheduler e ProcessBuilder

8
0

Aprenda a executar e monitorar scripts de shell com eficiência com suporte de sudo, diretórios de trabalho e controle completo de log.

Neste artigo, mergulharemos profundamente em como os usos de Dolphinscheduler ProcessBuilder Para executar comandos de shell. Por padrão, Dolphinscheduler envolve scripts de shell usando BashShellInterceptorBuilderGerando comandos de execução que suportam os modos padrão e sudo.

Também vamos caminhar por um Botagem da primavera Exemplo mostrando como configurar os diretórios de trabalho, mesclar fluxos de saída, monitorar a execução do processo e os logs de saída – ajudando você a obter gerenciamento e agendamento de tarefas da concha eficientes.

1. Como Dolphinscheduler usa o ProcessBuilder

1.1. Comandos de shell de embrulho

Em Dolphinscheduler, o embrulho de comando acontece dentro:

org.apache.dolphinscheduler.plugin.process.api.shell.ShellInterceptorBuilderFactory
public class ShellInterceptorBuilderFactory {

    non-public closing static String INTERCEPTOR_TYPE = PropertyUtils.getString("shell.interceptor.sort", "bash");

    @SuppressWarnings("unchecked")
    public static IShellInterceptorBuilder newBuilder() {
        // Default logic
        if (INTERCEPTOR_TYPE.equalsIgnoreCase("bash")) {
            return new BashShellInterceptorBuilder();
        }
        if (INTERCEPTOR_TYPE.equalsIgnoreCase("sh")) {
            return new ShShellInterceptorBuilder();
        }
        if (INTERCEPTOR_TYPE.equalsIgnoreCase("cmd")) {
            return new CmdShellInterceptorBuilder();
        }
        throw new IllegalArgumentException("Unsupported shell sort: " + INTERCEPTOR_TYPE);
    }
}

Por padrão, BashShellInterceptorBuilder é usado.

Aqui está a parte relevante:

org.apache.dolphinscheduler.plugin.process.api.shell.bash.BashShellInterceptorBuilder
public class BashShellInterceptorBuilder
        extends BaseLinuxShellInterceptorBuilder {

    @Override
    public BashShellInterceptorBuilder newBuilder() {
        return new BashShellInterceptorBuilder();
    }

    @Override
    public BashShellInterceptor construct() throws FileOperateException, IOException {
        // Core half: Generate shell script
        generateShellScript();
        Checklist bootstrapCommand = generateBootstrapCommand();
        // Instantiate BashShellInterceptor
        return new BashShellInterceptor(bootstrapCommand, shellDirectory);
    }

    @Override
    protected String shellInterpreter() {
        return "bash";
    }

    @Override
    protected String shellExtension() {
        return ".sh";
    }

    @Override
    protected String shellHeader() {
        return "#!/bin/bash";
    }
}

A geração de comando acontece aqui:

org.apache.dolphinscheduler.plugin.process.api.shell.BaseLinuxShellInterceptorBuilder#generateBootstrapCommand
protected Checklist generateBootstrapCommand() {
    if (sudoEnable) {
        // sudo -u tenant -i /decide/xx.sh
        return bootstrapCommandInSudoMode();
    }
    // bash /decide/xx.sh
    return bootstrapCommandInNormalMode();
}

Dois caminhos:

  • Modo regular (bash /path/to/script.sh)
  • Modo sudo (sudo -u tenant -i /path/to/script.sh)

Exemplo do modo sudo:

non-public Checklist bootstrapCommandInSudoMode() {
    Checklist bootstrapCommand = new ArrayList<>();
    bootstrapCommand.add("sudo");
    if (StringUtils.isNotBlank(runUser)) {
        bootstrapCommand.add("-u");
        bootstrapCommand.add(runUser);
    }
    bootstrapCommand.add("-i");
    bootstrapCommand.add(shellAbsolutePath().toString());
    return bootstrapCommand;
}

1.2. Executando o comando Shell

A verdadeira execução é tratada aqui:

org.apache.dolphinscheduler.plugin.process.api.shell.BaseShellInterceptor
public summary class BaseShellInterceptor implements IShellInterceptor {

    protected closing String workingDirectory;
    protected closing Checklist executeCommands;

    protected BaseShellInterceptor(Checklist executeCommands, String workingDirectory) {
        this.executeCommands = executeCommands;
        this.workingDirectory = workingDirectory;
    }

    @Override
    public Course of execute() throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.listing(new File(workingDirectory));  // Set working listing (necessary for loading JARs and so on.)
        processBuilder.redirectErrorStream(true);              // Merge error stream into output stream
        processBuilder.command(executeCommands);
        log.information("Executing shell command: {}", String.be part of(" ", executeCommands));
        return processBuilder.begin();
    }
}

2. Exemplo prático: agendamento de concha facilitada

Vamos criar um aplicativo de inicialização simples de primavera que inicie um script de shell!


2.1. Pom.xml Dependência


  org.springframework.boot
  spring-boot-starter
  2.6.1


2.2. Código do aplicativo de inicialização da primavera

@SpringBootApplication
public class Utility {

    public static void major(String[] args) throws Exception {
        SpringApplication.run(Utility.class, args);

        Checklist executeCommands = new ArrayList<>();
        executeCommands.add("sudo");
        executeCommands.add("-u");
        executeCommands.add("qiaozhanwei");
        executeCommands.add("-i");
        executeCommands.add("/decide/take a look at/my.sh");

        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.listing(new File("/decide/take a look at"));  // Set working listing
        processBuilder.redirectErrorStream(true);         // Merge error output into normal output
        processBuilder.command(executeCommands);

        Course of course of = processBuilder.begin();

        strive (BufferedReader inReader = new BufferedReader(new InputStreamReader(course of.getInputStream()))) {
            String line;
            whereas ((line = inReader.readLine()) != null) {
                // Print every line of output
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Watch for 10 minutes most
        boolean standing = course of.waitFor(10, TimeUnit.MINUTES);
        System.out.println("Execution standing -> " + standing);
    }
}

2.3. Exemplo de saída de log

Os logs mostram:

  • O script do shell foi executado com sucesso
  • Saídas padrão e de erro foram capturadas
  • O processo terminou em 10 minutos

Trecho:

Executing shell command : sudo -u qiaozhanwei -i /decide/take a look at/my.sh
...
Job job_1694766249884_0931 accomplished efficiently
standing ->true

Course of completed with exit code 0

Pensamentos finais

Usando Dolphinscheduler + ProcessBuildervocê pode lidar com flexibilidade de execução de tarefas de concha com controle complete sobre:

  • Diretórios de trabalho
  • Erro/fluxos de saída padrão
  • Permissões sudo
  • Monitoramento de tempo limite

Esta abordagem é simplesAssim, robustoe fácil de estender -Uma habilidade obrigatória se você estiver gerenciando fluxos de trabalho baseados em conchas em massive information ou DevOps Cenários!

fonte

DEIXE UMA RESPOSTA

Por favor digite seu comentário!
Por favor, digite seu nome aqui