我有一个使用Spring ThreadPoolTaskExecutor的REST API。 API在内部将可调用作业提交给ThreadPoolTaskExecutor,该调用会向第三方发送调用。一旦完成调用,就会执行业务逻辑并将结果返回给调用者。Spring:使用ThreadPoolTaskExecutor创建真正可伸缩的线程池
代码工作正常,但当负载增加时,性能变得非常糟糕。我怀疑这是ThreadPoolTaskExecutor的线程池大小的结果。所以说,如果并发用户是n,但我们只有x线程数(x小于n),那么x线程将不得不等待有限数量的线程来处理它们的请求。
我要处理的第三方调用平行,但不希望创建的线程数量庞大的线程池。
我的选择是使用Executors.newFixedThreadPool(y)。在方法内部使用它,一旦过程完成关闭对象。这是可能的但不能确定它的副作用,例如从方法创建固定线程池是否是一个好习惯。
其他选项可能是使用某种像GenericObjectPoolConfig对象池,并用它来获取线程。
其他选择可能是设置最大池大小,以Integer.max和减少队列容量为1。因此,每个新的请求到来,而不是存储在队列中的对象时,它会创建一个新的线程。
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(20);
threadPoolTaskExecutor.setMaxPoolSize(Integer.MAX_VALUE);
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.setQueueCapacity(1);
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
如果有人可以分享他的想法将是有益的。
@Configuration
public class TestConfiguration{
@Bean
public ConcurrentTaskExecutor concurrentTaskExecutor() {
ConcurrentTaskExecutor concurrentTaskExecutor = new ConcurrentTaskExecutor();
concurrentTaskExecutor.setConcurrentExecutor(getExecutor());
return concurrentTaskExecutor;
}
private Executor getExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(20);
threadPoolTaskExecutor.setMaxPoolSize(30);
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.setQueueCapacity(75);
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
@Service
public class TestServiceImpl{
@Autowired
private ConcurrentTaskExecutor concurrentTaskExecutor;
@Override
@Transactional
public DTO getDTO() {
Callable<TESTDTO> test1Callable = new Test1Callable();
Future<TESTDTO> testDTO1 = concurrentTaskExecutor.submit(test1Callable);
Callable<TESTDTO> test2Callable = new Test2Callable();
Future<TESTDTO> testDTO2 =concurrentTaskExecutor.submit(test2Callable);
Callable<TESTDTO> test3Callable = new Test3Callable();
Future<TESTDTO> testDTO3 =concurrentTaskExecutor.submit(test3Callable);
// Perform logic on DTO's
return DTO;
}
也许你的第一步是做一些仪器,并确认你的怀疑是否正确 - 我怀疑这是线程池size_的结果。确认瓶颈后,您可以查看解决方案。 – jay
线程池大小是原因。增加尺寸,提高性能。 – Suchit