你如何创建多个 Spring @RestControllers 每个都有自己的线程池?

How do you create multiple Spring @RestControllers each with their own thread pool?

我有一个 Spring RESTful 服务,使用 Tomcat web servlet 处理 2 种不同类型的数据,因此每种数据类型有 2 个休息控制器。 Controller #1 有可能使用大量内存执行密集型任务,因此我想在此控制器上最多允许 10 个连接。但是如果所有 10 个连接都在控制器 #1 上处理,我也希望控制器 #2 有自己的线程池,这样它可以在控制器 #1 已满时继续处理。

配置 Tomcat 的正确方法是在 application.yml 中设置其属性,如 spring 文档中 here 所述。 要设置最大连接总数,可以使用:

server.tomcat.max-connections: 10
server.tomcat.max-threads: 10

但是,这为整个应用程序配置了最大数量 connections/threads,两个控制器相结合。我需要每个控制器都有自己的线程池和自己的最大连接数。这可能吗?

你不能*。 Spring 引导设置一个嵌入式 Tomcat servlet 容器并注册一个 DispatcherServlet。整个 Tomcat 线程池用于处理所有通过 DispatcherServlet(或任何其他 servlets/filters 已注册)的请求。

* 您应该为每种类型的数据创建一个 ThreadPoolTaskExecutorExecutorService bean,然后将它们适当地注入您的 @Controller bean并把所有的工作分派给他们。

@Controlller
class FirstController {
    private final ExecutorService threadPool;

    public FirstController(@Qualifier("first-type-data") ExecutorService threadPool) {
        this.threadPool = threadPool;
    }

    @RequestMapping("/endpoint1")
    public CompletableFuture<Foo> handleEndpoint() {
        CompletableFuture<Foo> foo = new CompletableFuture<>();
        threadPool.submit(() -> {
            // handle all your business logic
            foo.complete(...);
        });
        return foo;
    }
}

Spring MVC "user space stack" 并不真正了解连接。您可以传递 HttpServletRequest 并保持您自己的计数。一旦达到阈值,您可以直接发回适当的响应,而无需启动任何业务逻辑。