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

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

作者:Java老兵(8年实战经验)


一、业务背景:为什么关心"同时处理请求数"?

在实际开发中,我们经常会被问到这样的问题:

  • "你这个服务能抗多少并发?"
  • "SpringBoot 默认能同时处理多少请求?"
  • "连接一多就卡,是不是线程池满了?"

这些问题本质上都在关注:服务的并发处理能力。在高并发场景下,比如秒杀、支付、直播、推送等系统,服务能否抗住压力直接影响用户体验和业务稳定。


二、SpringBoot 是怎么处理请求的?

1. SpringBoot 是什么?

SpringBoot 本质上是对 Spring 的封装,它让我们用更少的配置快速构建 Web 应用。而在 Web 层,SpringBoot 默认使用的是 嵌入式Servlet容器,比如:

  • Tomcat(默认)
  • Jetty
  • Undertow

2. 请求的处理流程(简化版)

复制代码
客户端请求 → SpringBoot内嵌容器(Tomcat) → 线程池(Executor) → Controller → 返回响应

关键点在于:Tomcat的工作线程池(connector executor)决定了能同时处理多少请求。


三、默认配置下,SpringBoot 能处理多少请求?

SpringBoot 默认使用 Tomcat,配置如下:

ini 复制代码
server.tomcat.max-threads=200
server.tomcat.min-spare-threads=10

也就是说:

  • 最多支持200个并发请求同时处理
  • 多出来的请求会被放在队列中(默认队列长度是100)

如果再多,超出队列长度,就会被拒绝或者连接超时。


四、如何验证和测试?

我们来实战验证下 SpringBoot 在不同线程数下的并发处理能力。

1. 创建一个模拟慢响应的接口

less 复制代码
@RestController
@RequestMapping("/test")
public class ConcurrencyTestController {

    /**
     * 模拟耗时接口,每个请求睡眠3秒
     */
    @GetMapping("/sleep")
    public String sleep(@RequestParam(defaultValue = "3000") long time) throws InterruptedException {
        Thread.sleep(time); // 模拟处理时间
        return "OK";
    }
}

2. 修改配置文件,设置线程池大小

ini 复制代码
server.tomcat.max-threads=20
server.tomcat.min-spare-threads=5
server.tomcat.accept-count=50

说明:

  • max-threads:最多同时处理20个请求
  • accept-count:请求队列长度,最多等待50个请求

五、压测验证

使用 Apache Benchmark (ab) 或 JMeter 进行压测:

bash 复制代码
ab -n 100 -c 50 http://localhost:8080/test/sleep

参数说明:

  • -n 100:总共发起100个请求
  • -c 50:并发50个请求

结果分析:

  • 由于 max-threads=20,只能同时处理20个请求
  • 剩下的30个进入队列(accept-count)
  • 如果并发超过70(20线程 + 50队列),就会出现连接被拒绝或超时

六、如何调优并发处理能力?

1. 提高 max-threadsaccept-count

ini 复制代码
server.tomcat.max-threads=500
server.tomcat.accept-count=1000

但线程多了也不是好事,线程上下文切换、内存占用都会增加。

2. 使用异步处理(@Async / CompletableFuture)

如果接口是 IO 密集型,可以考虑异步处理:

kotlin 复制代码
@RestController
public class AsyncController {

    @Autowired
    private AsyncService asyncService;

    @GetMapping("/async")
    public CompletableFuture<String> async() {
        return asyncService.doAsyncTask();
    }
}
typescript 复制代码
@Service
public class AsyncService {

    @Async
    public CompletableFuture<String> doAsyncTask() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // ignore
        }
        return CompletableFuture.completedFuture("Async OK");
    }
}

记得启用异步支持:

less 复制代码
@SpringBootApplication
@EnableAsync
public class Application { }

七、Tomcat线程池配置源码入口

SpringBoot 自动装配的 Tomcat 配置类是:

复制代码
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory

可以通过 Java 代码动态配置:

ini 复制代码
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
    return factory -> factory.addConnectorCustomizers(connector -> {
        ProtocolHandler handler = connector.getProtocolHandler();
        if (handler instanceof AbstractProtocol) {
            AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
            protocol.setMaxThreads(300);
            protocol.setAcceptCount(100);
        }
    });
}

八、总结

配置项 含义 默认值
max-threads 同时处理请求的最大线程数 200
accept-count 请求队列长度 100
min-spare-threads 最小空闲线程数 10

实战建议:

  • CPU密集型服务:控制线程数,防止过度切换
  • IO密集型服务:可以适当增加线程数,或使用异步
  • 高并发网站:使用Nginx + 多实例 + 负载均衡
  • 监控工具:推荐使用 Prometheus + Micrometer + Grafana 监控线程使用情况

九、写在最后

SpringBoot 本身并不限制并发能力,它的瓶颈来自于底层容器的线程池。作为一个有8年经验的Java开发者,我建议大家在开发高并发系统时,不仅要会调参数,更要结合业务特性选择同步、异步、反应式等不同模型。

并发不是拼参数,性能不是靠堆线程。

相关推荐
Moonbit1 分钟前
MoonBit Pearls Vol.03:01背包问题
后端·算法·编程语言
南囝coding17 分钟前
这个仓库堪称造轮子的鼻祖,建议看看!
前端·后端
JuiceFS26 分钟前
3000 台 JuiceFS Windows 客户端性能评估
后端·云原生·云计算
Cosolar35 分钟前
下一代 Python Web 框架?FastAPI 全面解析与实战对比
后端·python
用户4822137167752 小时前
C++——复合数据类型(数组、字符串)
后端
用户903700167152 小时前
分布式阻塞式限流学习及分享
后端
熊猫片沃子2 小时前
Mybatis中进行批量修改的方法
java·后端·mybatis
养鱼的程序员2 小时前
零基础搭建个人网站:从 Astro 框架到 GitHub 自动部署完全指南
前端·后端·github
白应穷奇2 小时前
编写高性能数据处理代码 01
后端·python
杨充2 小时前
03.接口vs抽象类比较
前端·后端