提交晚上执行的任务

Submitting tasks to be executed at night

我们有一个 Web 应用程序(基于 Spring),用户可以在其中提交一些 运行 在单个后台线程中的任务。我们正在使用 TaskExecutor 并为此提交 运行nables,一旦执行线程空闲,它们就会被处理。

现在我们想不是 运行 立即处理这些作业,而是在晚上的某个时间按顺序开始处理它们。到那个时候,他们都会排队等候。我们不知道一天会有多少工作,也不知道他们需要多少时间,所以我们不想在固定时间单独安排他们。

我查看了 Spring 的 Quartz 集成,但到目前为止我还没有发现任何有用的东西。如果这些挂起的作业以某种方式保留下来,以便它们能够在重新启动后继续存在,那就太好了。

有什么想法吗?提前致谢。

您可以使用 cron 表达式:

@Scheduled(cron = "* 2 * * *")
public void doSomething() {
}

例如,这会 运行 在 2 a.m。每天。

CronTrigger class 也可能对您有用,官方 Spring 文档中有一个简短的部分,您已在问题中链接了它。

让这些任务在重启后幸存下来的唯一方法是将它们及其数据保存在某种数据库中。

对于日程安排问题,我会在特定服务上使用 @Scheduled 注释,该注释将从数据库或执行程序的队列中调用任务,然后处理它们。

您可以采用的一种方法是将每个任务一提交就将其存储在数据库中。

然后,在晚上,您可以 运行 查询数据库并按顺序处理返回任务的作业。当每个任务的处理完成后,您可以从数据库中删除任务或将其标记为已处理。

如果正好有很多任务,可以分批处理。

该工作的草图可以是:

@Scheduled(cron = "some_time_at_night")
public void runJob() {
    // Query non processed tasks from the database
    List<Task> tasks = database.getNonProcessedTasks();
    // Iterated over returned tasks
    for (Task t : tasks) {
        try {
            // Process current task
            this.process(t);
            // Mark current task as processed in database or delete it
            database.updateTaskAsProcessed(t);
        } catch (Exception ex) {
            // Handle ex, either log it or store it for further reference
        }
    }
}

private void process(Task t) {
    // Perform processing here
}

Spring 通过 @Scheduled annotation 支持 cron 表达式。

您可以在调用 TaskExecutor 的方法上添加 @Scheduled 注释,如

示例:

@Scheduled (cron="0 0 2 * * ? *", fixedDelay = 5000)
public void updateEmployeeInventory(){
    System.out.println("Started fixed delay job");
    /**
     * add your scheduled job logic here
     */
}

fixedDelay : 如果您将固定延迟指定为 5 秒,则将每 5 秒以固定延迟调用一次带注释的方法,这意味着该时间段将是从每个先前调用的完成时间开始计算。

有关这方面的更多详细信息,请参见以下链接:-

  1. Schedule jobs using @Scheduled annotation in spring
  2. CronTrigger Tutorial