在Hazelcast DurableExecutorService上运行Cron作业

时间:2018-03-14 09:42:13

标签: spring scheduled-tasks quartz-scheduler hazelcast executorservice

我正在尝试在Hazelcast上的DurableExecutorService上运行cron计划。 我的想法是,如果一个节点因其计划而中断,其他具有备份的节点可以拾取并恢复CRON。 这就是我正在做的事情

        String cron = "0/5 * * * * *";

        config.setInstanceName(name);
        config.getDurableExecutorConfig("exec").setCapacity(200).setDurability(2).setPoolSize(8);

        HazelcastInstance instance = Hazelcast.newHazelcastInstance(config);
        DurableExecutorService executorService = instance.getDurableExecutorService("exec");

        executorService.executeOnKeyOwner(new EchoTask(name, cron), name);

我使用Spring CRON调度程序来实际运行CRON作业。

public class EchoTask implements Runnable, Serializable {

    private final String msg;
    private final String cronExpression;

    EchoTask(String msg, String cronExpression) {
        this.msg = msg;
        this.cronExpression = cronExpression;
    }
    public void run() {

            ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
            scheduler.initialize();
            scheduler.schedule(new Runnable() {

                @Override
                public void run() {

                    System.out.println("Executing" + msg);

                }
            }, new CronTrigger(cronExpression));

        }
}

现在,我跑了两次。实际上,有2个实例在运行。

  1. 在一个实例上执行实例-1
  2. 在另一个实例上执行实例-2
  3. 现在,我的理解是,如果我去杀死一个实例,让我们说1,那么node1的CRON应该迁移到node2。 但是,这种情况并没有发生。

    当我杀死节点时,我确实得到了这条消息

      

    信息:[192.168.122.1]:5707 [dev] [3.9.3]提交/回滚活着   成员[192.168.122.1]的交易:5709 -   26ed879b-8ce5-4d58-832c-28d2df3f7f87,UUID:   26ed879b-8ce5-4d58-832c-28d2df3f7f87

    我确信,我在这里遗漏了一些东西。 有人可以指导吗?

    编辑1:我确认对于正常任务,此行为有效,但由于某些原因,它不适用于Spring CRON

    编辑2 我怀疑的是,ThreadPoolTask​​Scheduler由于某种原因不可序列化。

      

    无法序列化   org.springframework.scheduling.concurrent.ThreadPoolTask​​Scheduler

    我怀疑,这就是为什么它不会持续存在于ringbuffer上。任何想法我怎么能使它Serializable。我检查了代码,ThreadPoolTask​​Scheduler已经实现了Serializable

2 个答案:

答案 0 :(得分:1)

executorService.executeOnKeyOwner(new EchoTask(name, cron), name)将在密钥所有者节点上运行。如果您没有启用备份并终止所有者节点,那么Hazelcast无法知道密钥曾经存在于集群中,因此没有持久性。

请参阅以下代码:

public class DurableExecutorServiceTest {

    DurableExecutorServiceTest() {
        Config config = new Config();
        config.getDurableExecutorConfig("MyService").setDurability(2).setCapacity(200).setPoolSize(2);

        HazelcastInstance hc = Hazelcast.newHazelcastInstance(config);
        hc.getMap("MyMap").put("Key-1", "Value-1");

        DurableExecutorService service = hc.getDurableExecutorService("MyService");
        service.executeOnKeyOwner(new MyRunnable(), "Key-1");

    }

    public static void main(String[] args) {
        new DurableExecutorServiceTest();
    }
}

class MyRunnable implements Runnable, Serializable {
    public void run() {
        int i = 0;
        while(true) {
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println("Printing in Durable executor service: "+i++);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

首先需要在执行此代码之前启动一个Hazelcast实例。启动时,它会加入先前运行的节点,并且可以在密钥的所有者节点上执行runnable。现在终止正在打印消息的节点,看看其他剩余节点是否选择了runnable。

如果您在设置中看到其他内容,那么您可能需要深入了解Spring cron作业。

答案 1 :(得分:0)

Thomas Kountis在https://groups.google.com/forum/#!topic/hazelcast/id8AcvWyR5I

回答
  

您好,

     

正如Jaromir上面所说,你基本上是在执行这条线   runnable scheduler.schedule(...)。一旦完成此指令,   你的Spring调度程序正在后台工作,但是从   DurableExecutor透视任务完成。任务完成后   完成后,它会被结果取代,在你的情况下没有   结果,null。如果您杀死该所有者成员,则备份为   提升,但不再有任务,因为我们已经取代了它   前一步。备份知道任务已完成。做这个   合理?

     

我无法以任何非滥用的方式来实现你的目标   寻找,除了可能是一个天真的CronScheduler里面   的IScheduledExecutor。想象一个周期性的任务,每一个都运行   第二个左右,它包含Map<CronExpression, Runnable>。   在run周期内,它检查表达式是否存在断言   任何runnable ready,如果是的话,运行另一个Executor(Durable或   专线)。由于这是一项定期任务,因此它可以很好地完成   IScheduledExecutor它会在失败时持久。

     

希望有所帮助!我们将寻求添加原生支持   将来IScheduledExecutor中的cron表达式。

     

由于