9

我遇到了必须使用持久调度程序的情况,因为我有一个 Web 应用程序可能由于某些问题而崩溃或关闭,并且如果发生这种情况可能会丢失它的作业详细信息。我尝试了以下方法:

  • 使用 Quartz 调度程序

RAMJobStore第一次使用,但由于它不是持久的,所以没有太大帮助。无法设置JDBCJobStore,因为这将需要对我现有的代码库进行大量代码更改。鉴于这种情况,我有以下疑问:

  • 如果我使用 Spring 的内置@Schedule注释,我的工作将是持久的..?我不介意作业是否在应用程序启动后安排。我想要的只是工作不会丢失他们的细节和触发器。?
  • 如果没有,是否有任何其他可以遵循的替代方案,请记住我需要使用我的调度程序安排多个作业。?
  • 如果我怎样才能做到这一点。?我的触发器是不同的每项工作。例如,我可能有一份工作安排在上午 9 点,另一个安排在上午 8.30 点,以此类推。
  • 如果不是调度程序,那么我可以有一个机制来处理这个。?

我发现一件事是 Quartz 的文档描述性不是很强。我的意思是顶级配置很好,但是在您的应用程序上配置它是一种痛苦。这只是一个旁注。与问题无关。

感谢帮助。:)

4

2 回答 2

11
  1. 不,Spring 的 @Schedule-annotation 通常只会指示 Spring 在什么时间应该安排某个任务在当前 VM 中运行。据我所知,也没有执行的上下文。时间表是静态的。

  2. 我有类似的要求,并创建了 db-scheduler ( https://github.com/kagkarlsson/db-scheduler ),这是一个简单、持久且对集群友好的调度程序。它将下一个执行时间存储在数据库中,并在到达时触发执行。

没有上下文的一个非常简单的示例RecurringTask可能如下所示:

final RecurringTask myDailyTask = ComposableTask.recurringTask("my-daily-task", Schedules.daily(LocalTime.of(8, 0)),
                () -> System.out.println("Executed!"));

final Scheduler scheduler = Scheduler
        .create(dataSource)
        .startTasks(myDailyTask)
        .threads(5)
        .build();

scheduler.start();

它将my-daily-task在每天 08:00 执行指定的任务。首次启动调度程序时,它将在数据库中调度,除非它已经存在于数据库中。

如果你想在未来某个时间安排一个临时任务,你可以使用OneTimeTask

    final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task",
            (taskInstance, context) -> System.out.println("One-time task with identifier "+taskInstance.getId()+" executed!"));

    scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
  1. 请参见上面的示例。只要 task-name 和 instanceIdentifier 是唯一的,就可以安排任意数量的任务。
于 2015-12-19T18:03:06.517 回答
8

@Schedule与实际执行人无关。默认的 java 执行器不是持久的(可能有一些特定于应用程序服务器的),如果你想要持久性,你必须使用Quartz来执行作业。

于 2013-10-03T06:58:29.720 回答