【问题标题】:Spring Cloud Data Flow Task Persist Arguments Between ExecutionsSpring Cloud Data Flow 任务在执行之间保持参数
【发布时间】:2020-09-07 12:11:09
【问题描述】:

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

在我的用例中,我需要为任务一次性设置命令行参数。

谢谢

【问题讨论】:

    标签: spring-batch spring-cloud-dataflow spring-cloud-task spring-cloud-dataflow-ui


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢,这就是我最终选择的道路,但让我根据环境创建了多个命令行运行器,我将在此处添加响应,以便人们从中受益。还有一件事,一旦设置了参数并且第一次启动了任务,如果我修改它们并没有完全覆盖以前的参数,它们就会被附加到列表中。我肯定会为这个用例打开一个故事。
    【解决方案2】:

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

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

    2. 第一个 CommandLineRunner:

      @组件 @Slf4j @Profile("产品") 公共类 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:

      @组件 @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_NAME”。 "属性键"="属性值"

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

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 2018-01-24
      • 2023-03-24
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      相关资源
      最近更新 更多