Heycm

Heycm

SpringBoot 可以同时处理多少个请求?

2024-07-18
SpringBoot 可以同时处理多少个请求?

一般我们说 SpringBoot 能够同时处理多少请求,指的是 Spring Web 容器的并发能力,那 SpringBoot 默认内置的 Web 容器默认是 Tomcat,也就是 Tomcat 的并发能力如何?

Tomcat 默认配置

我们看默认配置,如下:

server:
  tomcat:
    threads:
      # 最小工作线程数,黑奴,永远不能休息
      min-spare: 10
      # 最大工作线程数,临时工,有请求就打工,没请求就休息(销毁)
      max: 200
    # 连接队列大小,可以处理请求的最大数量
    max-connections: 8192
    # 等待连接队列大小,当最大连接数满时,请求被丢到这个队列
    accept-count: 100
    # 连接超时时间,指的是建立连接后,指定时间内未发生读写的最大时间,超时会断开
    connection-timeout: 60000
    # 连接存活时间,指的是完成当前http请求后,等待下一个http请求到来的超时时间
    keep-alive-timeout: ${server.tomcat.connection-timeout}
    # 同一个连接上允许的最大请求数,指的是在连接存活时间内,允许处理的最大请求数
    max-keep-alive-requests: 100

从默认配置可以看到,在不考虑硬件资源和操作系统的情况下,也就是理想状态 Tomcat 可以同时支持 8292 个 TCP 连接

max-connections + accept-count = 8292

当超过这个数量的 TCP 连接到达时,通常情况下会被 Tomcat 直接拒绝,响应 connection refused 错误,此时 Tomcat 已无额资源来处理这些连接。

但是,有可能受操作系统影响,若操作系统 net.core.somaxconn 网络参数设置比较大,连接会被操作系统层面暂时挂起,直到 TCP 客户端超时,或被 Tomcat 接收处理。

但,这并不代表 Tomcat 能够同时处理 8292 个请求。

Tomcat 理想并发能力

同样的,在不考虑硬件资源和操作系统的情况下

  • 最大工作线程数量 threads-max 设置为 200,每个线程处理一个请求

  • 即,Tomcat 可以同时处理 200 个请求

  • 假设处理每个请求耗时 10ms,那么计算 QPS = 200 * 1000 / 10 = 20000

这显然太理想化了。

Tomcat 实际并发能力

实际上,Tomcat 同时处理请求的能力,还有受 CPU、内存、操作系统等等各方面因素影响,并不能直接通过公式计算得到结果。

比如,我们知道现在操作系统都是分时操作系统,线程受操作系统调度分到 CPU 时间片,一个8核心的 CPU 在同一时刻也只能并行执行8个线程任务,与上述的理想值200差距太大。

那么,设置 200 个工作线程,操作系统不断地分配 CPU 时间片,不断地切换线程上下文,实际上线程是交替执行的,只是在一个时间段内“看起来”是同时执行,达到并发执行的效果,而切换线程上下文是需要付出成本的。

还有,内存资源也可能会限制任务执行,若内存不足,可能会发生频繁的内存清理工作,消耗 CPU 时间片资源。

另外,整个操作系统并非只为一个 Tomcat 服务,还有操作系统本身和其他程序,也会吃掉 CPU 资源等等情况,最后的体现在 Tomcat 上的表现就是单个请求处理时间变长,并发能力变低。

这些种种因素,会导致 Tomcat 的并发能力从理想值一直下降,因此,我们只能看具体情况,最好的办法就是进行压力测试,不断调整参数(当然不止Tomcat参数),找到相对高的并发点,这个点大概就是当前并发极限值,也就是我认为 SpringBoot 能同时处理多少个请求的答案。

❥(^_-)