0

我正在试验 SCDF 并成功地将 Spring Batch 作业作为任务运行。但是我遇到了任务参数持续存在的问题。似乎每次我需要执行任务时,我都应该为它提供命令行参数。

在我的用例中,我需要为任务一劳永逸地设置命令行参数。

在此处输入图像描述

谢谢

4

2 回答 2

2

这是设计使然。arguments每次启动任务应用程序时都必须传递任务应用程序,因为命令行参数并不意味着在后续任务启动之间传播。

只有deployment您在上面传递的任务属性Parameters被设计为在您启动后续任务启动时被持久化和重复使用。这些部署属性还包括任务application属性(带有app.前缀的那些)以及特定于平台的deployer属性(带有deployer.前缀的属性)。

鉴于这些设计方面,我同意可能会有用例(如您的用例)在任务启动之间传递相同的参数。因此,我建议您在这里创建一个包含您的具体案例的故事,我们将重新审视设计以扩大范围。

于 2020-05-21T01:53:06.753 回答
0

经过一些研究,我最终使用了参数而不是参数。

在此处输入图像描述

  1. 首先,我创建了一个带有多个 CommandLineRunner(在我的情况下为 2 个)的 Spring Batch,一个用于生产,它将使用将被 SCDF 参数覆盖的“应用程序属性”,另一个用于其他环境(DEV,...)将通过简单的命令行参数或 API 启动。

  2. 第一个 CommandLineRunner:

    @Component @Slf4j @Profile("prod") 公共类 ProdJobCommandLineRunner 实现 CommandLineRunner {

    @Value("${jobname}")
    private String jobName;
    
    @Value("${argument1}")
    private String argument1;
    
    @Value("${argument2}")
    private String argument2;
    
    @Autowired
    private ApplicationContext context;
    
    @Autowired
    private JobLauncher jobLauncher;
    
    @Override
    public void run(String... args) {
    
        log.info("Begin Launching Job with Args {}", Arrays.asList(args));
        log.error("JOB NAME: " + jobName);
    
        if (!CollectionUtils.isEmpty(Arrays.asList(args))) {
    
            JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
    
            jobParametersBuilder.addString("argument1", argument1);
            jobParametersBuilder.addString("argument2", argument2);
    
            try {
                Job job = (Job) context.getBean(jobName);
    
                jobLauncher.run(job, jobParametersBuilder.toJobParameters());
    
            } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
                log.error("Exception ", e);
            }
        }
        log.info("End Launching Job with Args {}", Arrays.asList(args));
    }
    

    }

  3. 第二个 CommandLineRunner:

    @Component @Slf4j @Profile("!prod") 公共类 DefaultJobCommandLineRunner 实现 CommandLineRunner {

    @Autowired
    private ApplicationContext context;
    
    @Autowired
    private JobLauncher jobLauncher;
    
    @Override
    public void run(String... args) {
    
        log.info("Begin Launching Job with Args {}", Arrays.asList(args));
    
        if (!CollectionUtils.isEmpty(Arrays.asList(args))) {
    
            Map<String, String> params = parseJobArgs(args);
            JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
    
            if (Boolean.parseBoolean(params.getOrDefault("force_restart", "false"))) {
                jobParametersBuilder.addString("force_restart", LocalDateTime.now().toString());
            }
    
            try {
    
                String jobName = params.get("job_name");
    
                log.info("JOB NAME: " + jobName);
    
                Job job = (Job) context.getBean(jobName);
    
                jobLauncher.run(job, jobParametersBuilder.toJobParameters());
    
            } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
                log.error("Exception ", e);
            }
        }
        log.info("End Launching Job with Args {}", Arrays.asList(args));
    }
    
    private Map<String, String> parseJobArgs(String[] args) {
        Map<String, String> params = new HashMap<>();
    
        Arrays.asList(args).forEach(arg -> {
            String key = StringUtils.trimAllWhitespace(arg.split("=")[0]);
            String value = StringUtils.trimAllWhitespace(arg.split("=")[1]);
    
            params.put(key, value);
        });
        return params;
    }
    

    }

  4. 在 SCDF 中导入应用程序,例如TESTAPP

在此处输入图像描述

  1. 根据您拥有的用例数量,使用同一个导入的应用程序创建多个任务

  2. 对于第一次启动的每个任务,请按照命名约定设置您拥有的参数:app. “APP_NAME”。"属性键"="属性值"

在这种情况下,例如它将是:app.TESTAPP.jobname=JOB_NAME

在此处输入图像描述

在此处输入图像描述

我希望这有帮助。

于 2020-05-21T12:59:02.983 回答