Spring Boot 中的多个请求是否由单线程处理,直到达到特定请求阈值?

问题描述 投票:0回答:2

在我的 Spring Boot 2.1.6 项目(基于 Tomcat)中,我有一个休息控制器。我添加了一个默认的构造函数来打印一些东西。我认为在基于 Tomcat 的服务器中,每个请求都是在单独的线程中处理的。因此,我希望每个请求都会触发一个新的控制器对象,并因此从构造函数中进行新的打印。但是,我进行了向其余控制器发送 30 个请求的测试,但我只看到打印了一次。据我了解,其余控制器在一个线程中处理所有这些请求。

我的问题是,是否确实在单个线程中处理多个请求,或者是否存在一定的请求阈值,在此阈值上将打开另一个线程?我正在使用默认的 Spring Boot 配置,也许这是在配置中的某个位置进行控制的?

这是我的控制器的代码:

@RestController
public class TrackingEventController {

    public TrackingEventController() {
        System.out.println("from TrackingEventController");
    }

    @RequestMapping(method=GET, path=trackingEventPath)
    public ResponseEntity<Object> handleTrackingEvent(
            @RequestParam(name = Routes.event) String event,
            @RequestParam(name = Routes.pubId) String pubId,
            @RequestParam(name = Routes.advId) String advId) {

        return new ResponseEntity<>(null, new HttpHeaders(), HttpStatus.OK);
    }
}
java spring-boot tomcat
2个回答
19
投票

您正在混合两个正交概念:

  1. 一条线
  2. 控制器实例

单个线程可以创建和/或使用一个或多个控制器实例。

多线程还可以创建和/或使用一个或多个控制器实例。

两者没有关系。

它的实际工作原理是

  • Spring bean 默认情况下是单例,因此 Spring 创建控制器的单个实例
  • Servlet 容器使用线程池。
  • 每次有请求到来时,都会从池中选择一个线程,并由该线程处理该请求。如果请求映射到您的控制器,则该线程将执行唯一控制器实例的适当方法。

如果您想知道哪个线程正在处理当前请求,请将其添加到您的控制器方法中:

System.out.println(Thread.currentThread().getName());

2
投票

Spring boot Tomcat 线程池默认大小为 200。您可以看到不同的线程服务于不同的请求。将调试点放在某个 REST 端点上,并从 Postman 等中多次调用它。从调试器中检查线程名称。 s.b.

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.