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;
}
あなたの疑問が正しかったかどうかを確認するための最初のステップは多分でしょうか?_これはスレッドプールサイズ_の結果であると思われます。ボトルネックが何であるかを確認した後、ソリューションを見ることができます。 – jay
スレッドプールのサイズが理由です。サイズを大きくすると、パフォーマンスが向上します。 – Suchit