Spring Boot服务器为何仅能同时处理2个请求?
兄弟,我之前踩过几乎一模一样的坑!结合你描述的现象——中等负载下客户端延迟/超时、服务器仅能同时处理2个请求,调大server.tomcat.max-threads后线程数也没超过10——大概率不是max-threads配置本身的问题,而是有其他隐藏的并发限制在起作用,咱们一个个排查:
1. 数据库连接池的并发瓶颈(最常见)
如果你的每个请求都需要访问数据库,数据库连接池的最大连接数限制是最可能的元凶。比如你用Spring Boot默认的HikariCP,如果spring.datasource.hikari.maximum-pool-size被误设为2,那么即使Tomcat线程池有10个线程,也只有2个能拿到数据库连接执行业务逻辑,剩下的线程都会阻塞在获取连接的环节,看起来就像服务器只能同时处理2个请求。
验证与解决:
- 检查应用日志,有没有类似
HikariPool-1 - Waiting for connection的等待日志; - 显式配置连接池最大连接数:
spring.datasource.hikari.maximum-pool-size=10 # 根据你的业务需求调整 - 用JConsole或JVisualVM监控连接池的活跃连接数,确认是否卡在2个。
2. Tomcat线程池的隐藏参数限制
虽然你调整了server.tomcat.max-threads,但Tomcat还有两个参数会直接影响线程池的实际扩容:
server.tomcat.max-spare-threads:控制线程池的空闲线程最大数,部分Tomcat版本默认值是max-threads的一半。如果你把max-threads设为20,但max-spare-threads默认是10,线程池最多只会维持10个活跃线程,不会再创建更多。你可以显式配置:server.tomcat.max-spare-threads=20 # 和max-threads保持一致或按需调整server.tomcat.max-connections:Tomcat能接受的最大TCP连接数,默认NIO连接器是10000,一般不会是这个问题,但如果被误设为很小的值,也会限制并发。
验证:
开启Spring Boot Actuator的Tomcat线程端点(引入spring-boot-starter-actuator并开启tomcat.threads端点),访问/actuator/tomcat/threads查看线程池的activeCount(活跃线程数)、poolSize(当前线程池大小)、maxThreads(配置的最大线程数),确认线程池是否真的没有按配置扩容。
3. 同步阻塞的业务逻辑占满线程
如果你的请求处理逻辑里有长时间的同步阻塞操作(比如调用外部API等待响应、大文件IO、锁等待等),即使线程池有10个线程,也会很快被全部阻塞,新请求只能排队等待,表现出延迟甚至超时。
解决思路:
- 将阻塞操作改为异步执行(比如用
CompletableFuture封装外部调用),释放Tomcat工作线程; - 适当增大
server.tomcat.max-threads,同时配合调整max-spare-threads,让线程池能创建更多线程处理阻塞任务。
4. 自定义过滤器/拦截器的并发限制
如果你的应用里自定义了Filter或Interceptor,有可能在这些组件里加了并发限制(比如用Semaphore限制同时执行的请求数),这也会导致服务器只能处理固定数量的请求。检查一下你的代码里有没有类似的限制逻辑。
内容的提问来源于stack exchange,提问作者adaj21

