Spring Boot-将计划的作业作为单独的进程运行

问题描述 投票:0回答:1

我有一个Spring Boot应用程序,该应用程序也很少执行计划的作业。我看不到任何功能问题。一项工作几乎每秒钟运行一次,以进行实时更新。也有其他工作。

我怀疑存在性能问题,尤其是当长时间运行的API击中控制器时。

// Heavy Job
@Scheduled(fixedRate = 10000)
public void processAlerts(){
}


@Scheduled(fixedDelayString = "${process.events.interval}")
public void triggerTaskReadiness() throws IOException {
    log.info("Trigger event processing job");
}
// Heavy Job to process data from different tables.
@Scheduled(fixedDelayString = "${app.status.interval}")
public void triggerUpdateAppHealth() throws IOException {
    log.info("Trigger application health");
}

是否可以将作业作为单独的流程进行。具有繁重工作的Spring Boot应用程序的最佳实践是什么?

mongodb spring-boot spring-scheduled
1个回答
0
投票

这个问题太笼统了,IMO。这完全取决于您的资源以及这项工作的确切功能。

Spring boot提供了一种通用的调度机制,但没有对工作性质做任何假设。

总的来说,当您执行繁重的工作时,CPU,网络,I / O和消耗的任何资源都是正确的(同样,取决于您的实际工作代码。)>]

如果从外部运行它,则假定另一个进程在同一服务器上运行,则另一个进程将消耗相同的资源。

从spring boot的角度来看,我可以说以下内容:

  1. 看起来像工作处理数据库。在这种情况下,Spring Boot支持与数据源,连接池,事务管理,更多高级API(例如JPA甚至是Spring数据)的集成,您也可以插入JOOQ之类的框架。最重要的是,它使使用数据库的实际工作更加容易。
  2. 您已经在问号中声明了Mongodb-好吧,spring在spring数据中还集成了mongo db。

最重要的是,如果您是在外部流程中运行该作业,那是您自己的事(这并不意味着它无法完成,只是意味着您失去了弹簧所带来的所有好处)

  1. AppHealth-弹簧启动已经提供了具有db运行状况端点的执行器功能,它还提供了一种创建自己的端点以检查任何具体资源的运行状况的方法(您可以在代码中实现它,因此您可以自由使用检查您想要的)。确保为正确的工作使用正确的工具。

  2. 关于控制器API。如果您使用的是传统的spring mvc,则tomcat具有用于API的线程池,因此从线程管理的角度来看,作业线程不会与控制器线程竞争,但是它们可能会共享相同的数据库连接,因此可能成为瓶颈。

  3. 关于@Scheduled的实现。默认情况下,将有一个线程来服务所有@Scheduled作业,这可能不足。

  4. 您可以通过创建自己的taskScheduler来更改此行为:

@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
    return Executors.newScheduledThreadPool(10); // allocate 10 threads to run @Scheduled jobs
}

您可能有兴趣阅读this discussion

  1. Spring @Scheduled始终在一个Spring管理的应用程序上下文的“边界内”工作。这样,如果您决定扩展实例,则每个实例都将运行“计划的”代码并执行繁重的工作。可以使用将Spring can be integrated用于群集模式的Quartz,您可以将其配置为每次选择一个节点并执行作业,但是由于您打算每秒运行一次,因此我怀疑石英是否能很好地工作。” >

  2. 一般观察:运行一组“繁重”的工作与“每秒运行”听起来并不好。这听起来似乎不合理,因为繁重的工作往往会持续超过1秒,因此这样做最终将占用所有资源,并且您将无法运行更多的工作。

© www.soinside.com 2019 - 2024. All rights reserved.