当前位置: 首页 > 知识库问答 >
问题:

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

华誉
2023-03-14

我在使用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>

然后我把这个添加到我的方法中:

@Transactional(value="transactionManagerClienti",readOnly=false)
@Scheduled(cron="0 03 7,10,13,15 * * MON-FRI")
@SchedulerLock(name = "syncCliente"
@Override
public void syncCliente() {
  ....
}
@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);
    }
@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();
    }

}

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

共有1个答案

孔永年
2023-03-14

我最近实现了一个简单的注释库dlock,它只在多个节点上执行一次计划任务。您可以简单地做如下所示的事情。

@Scheduled(cron = "59 59 8 * * *" /* Every day at 8:59:59am */)
@TryLock(name = "emailLock", owner = NODE_NAME, lockFor = TEN_MINUTE)
public void sendEmails() {
  List<Email> emails = emailDAO.getEmails();
  emails.forEach(email -> sendEmail(email));
}

完整配置请参见Github页面。

 类似资料:
  • 我用SpringBoot创建了一个简单的演示应用程序,其中包括执行器。带有@Scheduled注释的任务显示在执行器中,但以编程方式启动的任务不会显示。有没有办法让他们也出现? 我已经注释了@Enable调度。 我的组件如下所示: 执行器的结果仅显示带注释的任务:

  • 我正在编写一个应用程序,它有一个cron作业,每60秒执行一次。应用程序配置为在需要时扩展到多个实例。我只想每60秒在一个实例上执行一次任务(在任何节点上)。开箱即用,我找不到解决这个问题的方法,我很惊讶以前没有人问过多次。我使用的是Spring 4.1.6。

  • 我正在使用Spring,我有一个计划任务,可以对数据库进行一些操作。我发现这个任务是在每个池上执行的,而我只希望执行一次。例如,在我的日志文件中,我读到: 我有这样的配置: 这就是任务: 可能吗?谢谢

  • 我在parallelism 5上有一份flink的工作(目前!!)。其中一个richFlatMap流在打开(配置参数)方法中打开一个文件。在flatMap操作中,没有任何打开操作,它只是读取文件来搜索某些内容。(有一个实用程序类,它的方法类似于utilityClass.searchText(“abc”))。以下是样板代码: python脚本每天都会在特定时间更新此文件。因此,我还应该在flatMa

  • 问题3:如果我使用@Schedured(initaildelay=10000,fixedrate=20000)而不是@PostConstruct注释,它将解决第一个问题,但是它将每20秒执行一次我的作业。 有线索吗?

  • 问题内容: 是否可以在确切指定的时间仅安排一次Spring服务方法?例如,当前时间是下午2点,但是当我按下操作按钮时,我希望我的服务方法从晚上8点开始。我熟悉@Scheduled批注,但不确定如何编写cron表达式以使其不定期运行。这一次,每天晚上8点触发。 有什么建议? 问题答案: 您可以使用Spring的TaskScheduler的实现之一。我在下面提供了一个示例,该示例不需要太多配置(包装了