如何使用Spring启动只在集群内执行一次计划任务?

时间:2018-04-11 11:07:09

标签: spring spring-boot cron locking scheduled-tasks

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

我读到了https://github.com/lukas-krecan/ShedLock,所以我按照指南进行了操作,但它不起作用..这就是我所做的:

我把这些依赖包含在我的pom中:

TotalCustomersDaoImpl

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

public class TotalCustomersDaoImpl extends AbstractItemDao implements TotalCustomersDao

然后我配置我做的数据源:

  <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() {
  ....
}

但它没有用。

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

如何避免在春季启动的同时多次执行任务?

1 个答案:

答案 0 :(得分:0)

我最近实现了一个简单的注释库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 page进行完整配置。