如何使用Spring Boot在集群中仅执行一次计划任务?

Dro*_*ide 5 cron spring locking scheduled-tasks spring-boot

我在使用spring boot开发的Web应用程序中有一个计划任务。我在tomcat群集上运行它,因此在X小时,计划的任务从每个节点开始。

我读到以下内容:https : //github.com/lukas-krecan/ShedLock,所以我按照指南进行操作,但是它不起作用。

我在pom中包含了这些依赖项:

  <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-spring</artifactId>
        <version>0.18.2</version>
    </dependency>       
    <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-provider-jdbc</artifactId>
        <version>0.18.2</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

然后我将其添加到我的方法中:

@Transactional(value="transactionManagerClienti",readOnly=false)
@Scheduled(cron="0 03 7,10,13,15 * * MON-FRI")
@SchedulerLock(name = "syncCliente"
@Override
public void syncCliente() {
  ....
}
Run Code Online (Sandbox Code Playgroud)

然后我在哪里配置数据源:

@Configuration
@EnableJpaRepositories(basePackages = {"it.repository"}, entityManagerFactoryRef="entityManager", transactionManagerRef="transactionManager")
public class DataSourceMuxConfig {

    @Autowired
    private Environment environment;

    @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mux")
    public DataSource dataSource() throws NamingException {
        if(Arrays.asList(environment.getActiveProfiles()).contains("dev")) {
            return DataSourceBuilder.create().build();
        }else {
            Context ctxConfig = new InitialContext();
            return (DataSource) ctxConfig.lookup("java:comp/env/jdbc/mux");
        }
    }

    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcLockProvider(dataSource);
    }
Run Code Online (Sandbox Code Playgroud)

这是我的日程配置:

@Configuration
@EnableScheduling
@EnableAsync
public class SchedulerConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }

    @Bean
    public ScheduledLockConfiguration taskScheduler(LockProvider lockProvider) {
        return ScheduledLockConfigurationBuilder
            .withLockProvider(lockProvider)
            .withPoolSize(10)
            .withDefaultLockAtMostFor(Duration.ofMinutes(10))
            .build();
    }

}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

群集中的每个节点在执行此计划任务的同时执行。为什么?

如何避免使用Spring Boot同时执行多次任务?

per*_*rja 1

很晚的答案,但似乎您缺少注释 EnableSchedulerLock。如果没有该注释,所有实例都将在没有任何锁定的情况下运行调度。