在达到某些请求阈值之前,Spring Boot中的单线程是否会处理多个请求?

hit*_*ker 3 java tomcat spring-boot

在我的Spring Boot 2.1.6项目(基于Tomcat)中,我有一个rest控制器。我向它添加了一个默认的构造函数,它可以打印一些内容。我认为在基于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 7

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

  1. 一个线程
  2. 控制器实例

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

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

两者无关。

它实际上是如何工作的

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

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

System.out.println(Thread.currentThread().getName());
Run Code Online (Sandbox Code Playgroud)

  • 是和不是。如果控制器确实具有可变状态,那么是的。如果不是,大多数情况下都是(或至少应该是)这种情况,并且您发布的示例就是这种情况,那么同步就没用了。 (4认同)
  • 因此,如果多个线程可能访问同一个单例控制器,那么我的工作就是同步控制器内的代码,对吧?但是我添加的同步越多,我从每个请求模型的线程中获得的好处就越少。那里的最佳实践是什么? (3认同)