简体   繁体   English

Spring Boot:我们可以为每个请求设置单独的线程池吗?

[英]Spring Boot: Can we have seperate thread pool for each request?

I've implemented asynchronous execution for a method in my application using Spring Boot @Async.我已经使用 Spring Boot @Async 为我的应用程序中的一个方法实现了异步执行。 I'm having a custom thread pool with 20 thread.我有一个带有 20 个线程的自定义线程池。 In a for loop calling the async method for 30 times.在 for 循环中调用异步方法 30 次。

Each individual request is executing asynchronously but when i made two different requests at the same time to my API from browser, first request is executing and then second.每个单独的请求都是异步执行的,但是当我同时从浏览器向我的 API 发出两个不同的请求时,第一个请求正在执行,然后是第二个。 Not both requests executing the same method parallely.不是两个请求并行执行相同的方法。

I thought when first request reach the app, it's started executing the async method and since it's being executing for 30 times and my pool is having 20 threads, all threads are busy in executing first request.我想当第一个请求到达应用程序时,它开始执行 async 方法,因为它执行了 30 次并且我的池有 20 个线程,所有线程都忙于执行第一个请求。 So even second request came for execution also since the pool of threads busy, the other request is waiting till a thread becomes free in the pool.因此,由于线程池繁忙,即使第二个请求也被执行,另一个请求正在等待,直到线程池中的线程空闲。

Can we have separate thread pool for each individual request.我们可以为每个单独的请求设置单独的线程池吗? or any way that we can make execution of each request separate independent of other request processing.或者我们可以使每个请求的执行独立于其他请求处理的任何方式。

Here is my code sample.这是我的代码示例。

@SpringBootApplication
@EnableAsync
public class AppBootStrap
{
  public static void main(String[] args)
  {
    SpringApplication.run(AppBootStrap.class, args);
  }

  @Bean
  public AsyncTaskService asyncTaskService() {
    return new AsyncTaskService();
  }

  @Bean(name="customExecutor")
  public Executor taskExecutor() {
    ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor();
    poolExecutor.setCorePoolSize(10);
    poolExecutor.setMaxPoolSize(20);
    poolExecutor.setThreadNamePrefix("customPoolExecutor");
    poolExecutor.initialize();
    return poolExecutor;
  }
}

**Controller Class:**

@RestController
public class TaskController
{
  @Autowired
  private TaskService taskService;

 @RequestMapping("/performAction")
 public void performAction() {
    taskService.performAction();
 }
}

**Service class**

@Service
public class TaskService
{
  @Autowired
  private AsyncTaskService asyncTaskService;

  public void performAction()
  {
    for(int i = 0; i < 30; i++) {
        asyncTaskService.greetings(i);
    }
  }
}

**Async Method Class**

public class AsyncTaskService
{
  @Async
  public void greetings(Integer i)
  {
    try
    {
        Thread.sleep(500 * (i + 10));
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }
    System.out.println("Welcome to Async Service: " + i);
  }
}
    @Bean(name = "apiTaskExecutor")
    public ThreadPoolTaskExecutor apiTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(20);
    executor.setMaxPoolSize(100);
    executor.setQueueCapacity(50);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
}

@Bean(name = "lruTaskExecutor")
    public ThreadPoolTaskExecutor lruTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(100);
    executor.setMaxPoolSize(200);
    executor.setQueueCapacity(500);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
}

The Way to do this is to create two Thread different Thread Pools using Different Qualifier names.这样做的方法是使用不同的限定符名称创建两个线程不同的线程池。 (As shown above) (如上图)

    @Autowired
    @Qualifier("apiTaskExecutor")
    private ThreadPoolTaskExecutor apiTaskExecutor;

Then autowire the required pool using the qualifier you have given .然后使用您提供的限定符自动装配所需的池。 You can also use the @Async annotation instead of autowiring .您还可以使用@Async批注代替@Async I prefer this way.我更喜欢这种方式。

If I am not wrong this way of having different thread pools for different Tasks is known as bulkhead pattern.如果我没有错的话,这种为不同任务设置不同线程池的方式被称为舱壁模式。

I think the problem is that the customExecutor bean is a singleton.我认为问题在于 customExecutor bean 是一个单例。 This means that when the second request tries to use this bean it finds all the threads of the thred pool busy.这意味着当第二个请求尝试使用这个 bean 时,它发现线程池的所有线程都忙。 You can try to make the customExecutor bean non-singleton by using the @Scope("prototype") annotation which will cause a new one to be instantiated whenever a bean of this type is requested.您可以尝试使用 @Scope("prototype") 注释使 customExecutor bean 成为非单例,这将导致在请求此类型的 bean 时实例化一个新的 bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何自定义spring boot embedded tomcat线程池? - How can I customize spring boot embedded tomcat thread pool? 为Spring Boot异步TaskExecutors配置线程池? - Configuring a thread pool for Spring Boot asynchronous TaskExecutors? Spring Boot应用程序的tomcat中的默认线程池 - Default thread pool in tomcat of a spring boot application 即使我们有一个线程池,我的ThreadLocal如何重置每个请求 - How does my ThreadLocal gets reset every request even though we have a thread pool Spring启动请求和线程分配 - Spring boot request and thread allocation 我们如何在春季启动时将巨大的有效载荷限制为POST请求 - How can we restrict the huge payload to POST request in spring boot 每个 api 请求中的线程池与单个应用程序池重用 - Thread pool in each api request vs single application pool reuse 在现有的 spring-boot 应用程序中,在单独的线程中运行无限循环 - In a existing spring-boot application, run a infinite loop in a seperate thread 我们可以创建一个Spring ScheduledExecutorTask池吗? - Can we create a pool of Spring ScheduledExecutorTask? 我们如何知道,如果Spring Boot应用程序正在使用连接池 - How to do we know , if spring boot application is using connection pool
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM