Java 我是否应该为spring controller中的每个请求创建executor服务?

Java 我是否应该为spring controller中的每个请求创建executor服务?,java,spring,spring-boot,Java,Spring,Spring Boot,我试图构建一个RESTAPI控制器,它将主机名列表作为输入,并在每个主机名中执行一个命令 @RequestMapping("/tasks") public Result execute(@RequestParam(value="hostList") List<HostName> hosts, String command) { //1. Execute the command in each hostname asynchronously and get co

我试图构建一个RESTAPI控制器,它将主机名列表作为输入,并在每个主机名中执行一个命令

@RequestMapping("/tasks")
    public Result execute(@RequestParam(value="hostList") List<HostName> hosts, String command) {
        //1. Execute the command in each hostname asynchronously and get completable future.
        //2. Get a list of completable future for each hostname command execution
        //3. Wait for them to complete and then compose the result
    }
问题是,步骤1需要为每个主机名异步执行。 我计划为每个请求创建一个线程池大小为hosts.size的executor服务,然后在该线程池中执行步骤1

但我认为为每个请求创建executor是个坏主意,因为这样会消耗大量内存

这是正确的前进方向,还是在spring中内置了一些东西来处理这个场景


请注意,主机列表可能从1到20不等。不,没有理由为每个请求创建新的执行器。您应该有一个执行者,当您的请求到来时,您的代码应该创建许多可运行的任务并将它们提交给执行者。同样在您的情况下,因为您正在谈论在不同的主机上运行某些命令,这意味着您不在服务器上运行任何命令。您以某种方式向相关主机发送一条消息,其中包含要执行的命令。我假设你是排队的。因此,即使您愿意,也无法同步执行您的命令,因为每个命令都在不同的主机上执行。因此,显然它们不能在同一进程中运行,更不用说在同一线程中运行了。所以在你的情况下,你可能根本不需要任何遗嘱执行人

否,没有理由为每个请求创建新的执行器。您应该有一个执行者,当您的请求到来时,您的代码应该创建许多可运行的任务并将它们提交给执行者。同样在您的情况下,因为您正在谈论在不同的主机上运行某些命令,这意味着您不在服务器上运行任何命令。您以某种方式向相关主机发送一条消息,其中包含要执行的命令。我假设你是排队的。因此,即使您愿意,也无法同步执行您的命令,因为每个命令都在不同的主机上执行。因此,显然它们不能在同一进程中运行,更不用说在同一线程中运行了。所以在你的情况下,你可能根本不需要任何遗嘱执行人

没有理由为每个请求创建新线程。您可以拥有由执行者创建的具有固定大小N的线程池,也可以在Tomcat/用于满足HTTP请求的任何其他提供程序线程上提交任务。我在下面给出了两个可能适用于您的一个用例的解决方案

下面的解决方案适用于您希望客户端等待其命令提交到其主机的情况

您应该向主机发送一条消息来执行命令,可能是通过RESTAPI或其他任何方式,然后等待这些任务被执行或提交:这一切都取决于您的用例

下面的解决方案适用于您希望能够将命令排队的情况

您可以将任务提交到创建的线程池,该线程池将按FI-FO顺序执行您的任务。
根据您的用例,您可以使用1个或多个线程,而不是太多线程,因为这只会降低线程池中线程的整体性能。这些任务将在从队列中选取时执行。

没有理由为每个请求创建新线程。您可以拥有由执行者创建的具有固定大小N的线程池,也可以在Tomcat/用于满足HTTP请求的任何其他提供程序线程上提交任务。我在下面给出了两个可能适用于您的一个用例的解决方案

下面的解决方案适用于您希望客户端等待其命令提交到其主机的情况

您应该向主机发送一条消息来执行命令,可能是通过RESTAPI或其他任何方式,然后等待这些任务被执行或提交:这一切都取决于您的用例

下面的解决方案适用于您希望能够将命令排队的情况

您可以将任务提交到创建的线程池,该线程池将按FI-FO顺序执行您的任务。
根据您的用例,您可以使用1个或多个线程,而不是太多线程,因为这只会降低线程池中线程的整体性能。这些任务将在从队列中选取时执行。

是否存在不能重用1 Executor服务的原因?对于每个新实例,您都在分配新线程,这相当昂贵。此外,创建的线程数量超出CPU的处理能力,这对您没有任何好处。@ŠimonKocúrek对于无法使用非阻塞IO的I/O驱动的工作负载,拥有比CPU核心更多的线程是有意义的。但是我同意一个单一的、应用程序范围的executor看起来更好,只要能够控制总的资源限制就行了?对于每个新实例,您都在分配新线程,这相当昂贵。另外,创建的线程比
您的CPU可以处理任何事情都不会给您带来任何好处。@ŠimonKocúrek对于不能使用非阻塞IO的I/O驱动的工作负载,拥有比CPU核心更多的线程是有意义的。但是我同意一个单一的应用程序范围的执行器似乎更好,只要能够控制总的资源限制。我同意你的回答,他不应该为每个请求创建一个新的执行器/线程,但是,我不同意你关于不能同步执行命令的评论。您仍然能够通过某种第三系统同步执行命令,该系统保持每个主机的已到达命令的状态,然后在到达该障碍后执行命令。接下来,您可以使用一个执行器,因为您可能只想发出您的请求,让执行器/线程池执行您的任务,让客户端继续,而不是等待NIO appr。@Remco Buddelmeijer-我想这有点没有实际意义,但我想您是对的。他可以运行所有任务,然后返回答案,即同步执行。但是,它仍然有一个异步组件,因为他必须与不同的主机通信。我同意你的回答,他不应该为每个请求创建一个新的执行器/线程,但是,我不同意你关于不能同步执行命令的评论。您仍然能够通过某种第三系统同步执行命令,该系统保持每个主机的已到达命令的状态,然后在到达该障碍后执行命令。接下来,您可以使用一个执行器,因为您可能只想发出您的请求,让执行器/线程池执行您的任务,让客户端继续,而不是等待NIO appr。@Remco Buddelmeijer-我想这有点没有实际意义,但我想您是对的。他可以运行所有任务,然后返回答案,即同步执行。但仍然有一个异步组件,因为他必须与不同的主机通信