gpt4 book ai didi

java - Spring Boot 中的多线程 cron 作业

转载 作者:行者123 更新时间:2023-11-30 05:23:33 26 4
gpt4 key购买 nike

我正在开发一个 Spring Boot 应用程序,该应用程序在给定网站中查找给定关键字,并在找到匹配项时废弃网页。我正在编写一个 cron 作业,每 5 分钟刷新一次结果,如下所示:

@Scheduled(cron = "* */5 * * * *")
public void fetchLatestResults() throws Exception {
LOG.debug("Fetching latest results >>>");
List<Keyword> keywords = keywordService.findOldestSearched10();
keywordService.updateLastSearchDate(keywords);
searchResultService.fetchLatestResults(keywords);
LOG.debug("<<< Latest results fetched");
}

数据库有 100 个关键字,在 cron 作业中,我首先列出最后获取结果的最旧的 10 个关键字。因此,例如,第一次运行应使用 ids 1 到 10 的keywords,第二次运行应使用 ids 11 到 20,依此类推,第 11 次运行应再次使用 ids 1 到 10,然后该过程继续.

现在的问题是执行搜索所需的时间远远超过 5 分钟。因此,尽管我已将 cron 作业设置为每 5 分钟运行一次,但在第一次运行完成之前,第二次运行不会发生。因此,完成搜索需要花费数小时。如何使该进程成为多线程,以便 cron 作业的多个实例可以同时运行,因为它们在不同的关键字列表上运行?

最佳答案

我建议您异步执行 cron 作业。

创建 executor 类,该类将创建一个新线程来运行您的 cron 作业:

@Component
public class YourCronJobExecutor {

private int threadsNumber = 10;
private ExecutorService executorService;

@PostConstruct
private void init() {
executorService = Executors.newFixedThreadPool(threadsNumber);
}

/**
* Start.
* @param runnable - runnable instance.
*/
public void start(Runnable runnable) {
try {
executorService.execute(runnable);
} catch (RejectedExecutionException e) {
init();
executorService.execute(runnable);
}
}
}

创建一个包含 cron 作业逻辑的 processor 类:

@Component
public class CronJobProcessor {

//logger
//autowired beans

public void executeYouCronJob() {
LOG.debug("Fetching latest results >>>");
List<Keyword> keywords = keywordService.findOldestSearched10();
keywordService.updateLastSearchDate(keywords);
searchResultService.fetchLatestResults(keywords);
LOG.debug("<<< Latest results fetched");
}
}

最后,您的 cron 作业类将如下所示:

@Component
public class YourCronJobClass {

private final YourCronJobExecutor yourCronJobExecutor;

private final CronJobProcessor cronJobProcessor;

@Autowired
public PopulateCourseStateController(YourCronJobExecutor yourCronJobExecutor,
CronJobProcessor cronJobProcessor) {
this.yourCronJobExecutor = yourCronJobExecutor;
this.cronJobProcessor = cronJobProcessor;
}

@Scheduled(cron = "* */5 * * * *")
public void fetchLatestResults() throws Exception {
yourCronJobExecutor.start(cronJobProcessor::executeYouCronJob);
}
}

这样,您的 cron 作业的执行将花费几毫秒的时间,并且实际执行该作业的单独线程将根据需要运行。

但是,也许您希望在单独的线程中执行每个关键字的搜索,但这有点不同。

关于java - Spring Boot 中的多线程 cron 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59100472/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com