Java 在Spring boot中使用两个执行器运行并行作业
我已经创建了一个SpringBoot应用程序,它将接受作业请求并在后台运行它们。 这些作业请求非常密集,如果由单线程处理,则需要4-5个小时。 在内部,这些作业请求有单独的较小任务,大约300-400个。所以我创建了一个任务执行器来并行处理它们。它很有魅力,在35分钟内完成了一切。但当另一个作业与此作业并行运行时,问题就出现了。现在做同样的工作需要两个小时。起初,我认为可能是一个作业占用了所有线程,让其他作业等待。因此,为了解决这个问题,我创建了另一个执行者,并将其分配给每个工作。但没有改善 顺便说一下,内部任务在内部调用数据库 下面是任务执行器的配置以及我如何在方法上使用Java 在Spring boot中使用两个执行器运行并行作业,java,oracle,spring-boot,executorservice,hikaricp,Java,Oracle,Spring Boot,Executorservice,Hikaricp,我已经创建了一个SpringBoot应用程序,它将接受作业请求并在后台运行它们。 这些作业请求非常密集,如果由单线程处理,则需要4-5个小时。 在内部,这些作业请求有单独的较小任务,大约300-400个。所以我创建了一个任务执行器来并行处理它们。它很有魅力,在35分钟内完成了一切。但当另一个作业与此作业并行运行时,问题就出现了。现在做同样的工作需要两个小时。起初,我认为可能是一个作业占用了所有线程,让其他作业等待。因此,为了解决这个问题,我创建了另一个执行者,并将其分配给每个工作。但没有改善 顺
@Bean(name = "taskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.setMaxPoolSize(200);
executor.setQueueCapacity(200);
executor.setThreadNamePrefix("Thread1-");
executor.initialize();
return executor;
}
@Bean(name = "exTaskExecutor")
public Executor exThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(30);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("Thread2-");
executor.initialize();
return executor;
}
@Async("taskExecutor")
public void job1()
//do something
}
@Async("exTaskExecutor")
public void job2()
//do something
}
//database connections
spring.datasource.hikari.connectionTimeout=60000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.autoCommit=true
spring.datasource.hikari.maximumPoolSize=120
spring.datasource.hikari.connection-test-query: SELECT 1 FROM DUAL
我不明白问题出在哪里?是在任务执行器中还是在HikariCP中?
从日志中我所能看到的是,两个执行器的线程在任何时候都不是并行运行的。
非常感谢任何帮助或替代方法。这里的主要问题是可用处理器的数量,您只能并行运行
n
线程(n==可用处理器)
等于可用处理器的数量,剩余的将同时运行,例如,您可以使用运行时类来检查可用的处理器
Runtime.getRuntime().availableProcessors() // In my case 8
我有总共4个超线程处理器,每个超线程处理器可以并行处理两个线程,铰孔线程将同时运行,而且您可以在这里了解更多信息,正如@Deadpool所说,您需要了解进程在哪里受到限制。您可能需要扩展(即一台cpu较多的机器)或跨多台机器扩展。向外扩展可能需要、或其他可扩展的工作管理器。谢谢您的回复。我以前看过所有这些文件。我忘了提到,我们使用了简单线程,通过保持Thread.sleep几秒钟来运行这些内部作业(没有执行器),并在没有连接池的情况下连接到oracle数据库,它在1.5小时内完成了这两个作业。但对于遗嘱执行人,正如我所说,这需要很多时间。我不想使用简单的线程机制,因为它是老式的,需要很多资源。另外,我给出的指标来自同一台机器,这台机器是一台具有2个内核的windows服务器。您以前在没有执行器的情况下根据需要创建线程,现在您正在创建100个线程并重新使用它们,当您创建线程池时,线程调度程序会在创建线程时为所有线程分配相等的资源(CPU)。我想说的是,尽可能降低这些数字@karepuThis系统最多可供3人使用,他们在任何时候提交2份工作。这就是我们不想扩大资源规模的原因。我还详细解释了@Deadpool answer,作为对我的基准的评论。但是谢谢你的回答。