如何让JobRegistry包含Spring批处理服务器重启时的作业信息

问题描述 投票:0回答:1

我们有一个场景,每当作业执行 STARTED 状态时,服务器可能会崩溃。在这种情况下,要重新启动批处理,我从这里理解Spring Batch在服务器故障后恢复,需要将batch_job_execution和batch_step_execution中的status和end_time列值从STARTED更新为FAILED,JobOperator.restart(jobExecutionId) API才能工作。

但是调用它会给出“NoSuchJobException:没有注册名称为 [] 的作业配置”,因为 JobOperator 内的 jobRegistry 映射是空的。

现在如何在服务器重新启动时使用这些作业信息重新填充 JobRegistry,以便我们可以调用 JobOperator.restart(jobExecutionId)。

下面是我的代码

/** The Test properties. */
  @Autowired
  private TestProperties TestProperties;

  @Primary
  @Bean(name = "TestDataSource")

  public DataSource batchDataSource() {
    DataSource TestDBSrc = DataSourceBuilder.create().username(getUsername()).password(getPassword()).url(getUrl()).build();
    if (TestDBSrc != null && TestDBSrc instanceof HikariDataSource) {
      @SuppressWarnings("resource")
      HikariDataSource hikariDatsource = (HikariDataSource) TestDBSrc;
      hikariDatsource.setSchema(getSchema());
    }
    return TestDBSrc;
  }

  private String getSchema() {
    return TestProperties.getValue("spring.datasource.hikari.schema", "");
  }

  private String getUsername() {
    return TestProperties.getValue("spring.datasource.username", "");
  }

  private String getPassword() {
    return TestProperties.getValue("spring.datasource.password", "");
  }

  private String getUrl() {
    return TestProperties.getValue("spring.datasource.jdbc-url", "");
  }

  @Bean(name = "transactionManager")
  public JdbcTransactionManager batchTransactionManager(@Qualifier("TestDataSource") DataSource dataSource) {
    return new JdbcTransactionManager(dataSource);
  }

  @Bean(name = "TestBatchJobRepository")
  public JobRepository jobRepository(@Qualifier("TestDataSource") DataSource batchDataSource,
      @Qualifier("transactionManager") JdbcTransactionManager batchTransactionManager) throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(batchDataSource);
    factory.setTransactionManager(batchTransactionManager);
    factory.afterPropertiesSet();
    return factory.getObject();
  }

  @Bean(name = "TestBatchJobLauncher")
  public JobLauncher jobLauncher(@Qualifier("TestBatchJobRepository") JobRepository jobRepository) throws Exception {
    TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    jobLauncher.afterPropertiesSet();
    return jobLauncher;
  }

  @Bean (name = "TestBatchJobExplorer")
  public JobExplorer jobExplorer(@Qualifier("TestDataSource") DataSource dataSource,@Qualifier("transactionManager")JdbcTransactionManager batchTransactionManager) throws Exception {
      final JobExplorerFactoryBean bean = new JobExplorerFactoryBean();
      bean.setDataSource(dataSource);
      bean.setTransactionManager(batchTransactionManager);
      bean.setTablePrefix("BATCH_");
      bean.setJdbcOperations(new JdbcTemplate(dataSource));
      bean.afterPropertiesSet();
      return bean.getObject();
  }
  
  @Bean (name ="TestBatchJobRegistry")
  public JobRegistry jobRegistry() throws Exception {
    return new MapJobRegistry();
  }
  
  @Bean
  public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(@Qualifier("TestBatchJobRegistry") JobRegistry jobRegistry) {
      JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
      postProcessor.setJobRegistry(jobRegistry);
      return postProcessor;
  }
  
  @Bean (name = "TestBatchJobOperator")
  public JobOperator jobOperator(@Qualifier("TestBatchJobLauncher") JobLauncher jobLauncher, @Qualifier("TestBatchJobRepository") JobRepository jobRepository,
          @Qualifier("TestBatchJobRegistry") JobRegistry jobRegistry, @Qualifier("TestBatchJobExplorer") JobExplorer jobExplorer) {
      final SimpleJobOperator jobOperator = new SimpleJobOperator();
      jobOperator.setJobLauncher(jobLauncher);
      jobOperator.setJobRepository(jobRepository);
      jobOperator.setJobRegistry(jobRegistry);
      jobOperator.setJobExplorer(jobExplorer);
      return jobOperator;
  }
}

这里因为我使用的是默认的内存映射

@Bean (name ="TestBatchJobRegistry")
  public JobRegistry jobRegistry() throws Exception {
    return new MapJobRegistry();
  }

服务器重启后它会被清除。

spring-boot spring-data spring-batch spring-batch-admin spring-batch-job-monitoring
1个回答
0
投票

情况不应该是这样,因为您已经注册了

JobRegistryBeanPostProcessor
。这是 bean 后处理器,每次(重新)启动 Spring 应用程序上下文时都会填充作业注册表。

© www.soinside.com 2019 - 2024. All rights reserved.