Spring Boot 2.5.8嵌入式Tomcat无法从同一源IP建立多端口并发连接的问题排查与解决
这种单连接正常、多并发连接卡壳的情况,我在处理Spring Boot嵌入式Tomcat问题时碰到过好几次,结合你的Wireshark抓包信息,咱们可以从这几个方向逐一排查:
1. Tomcat核心连接参数配置受限
Spring Boot 2.5.8默认用NIO模式的Tomcat,虽然默认的maxConnections(最大同时连接数)是10000,acceptCount(连接等待队列大小)是100,但如果你的应用曾修改过这些参数,或者某些自定义配置覆盖了默认值,就可能导致新连接被拒绝。比如如果不小心把maxConnections设成1,那自然只能处理一个连接。
解决方法:
在application.properties或application.yml里明确配置这两个参数:
# 最大同时连接数,根据服务器性能调整 server.tomcat.max-connections=20000 # 连接等待队列大小,建议和操作系统的somaxconn参数一致 server.tomcat.accept-count=1000
2. 操作系统层面的TCP连接限制
即使Tomcat配置没问题,操作系统的TCP栈参数也可能拖后腿。比如Linux下的net.ipv4.tcp_max_syn_backlog(SYN半连接队列大小)和net.core.somaxconn(全连接队列大小)如果设置过小,当并发连接请求过来时,服务器会直接丢弃超出队列的SYN包,这就会出现你看到的第二个连接无法建立的情况。
解决方法:
- 查看当前参数值:
sysctl net.ipv4.tcp_max_syn_backlog sysctl net.core.somaxconn - 修改参数(临时生效,重启后会恢复):
sysctl -w net.ipv4.tcp_max_syn_backlog=4096 sysctl -w net.core.somaxconn=1000 - 要永久生效,把这两行添加到
/etc/sysctl.conf文件,然后执行sysctl -p加载配置。
另外,还要检查服务器防火墙(比如iptables、firewalld)有没有针对8081端口设置并发连接限制,有的话需要调整规则。
3. Tomcat线程池耗尽导致无法处理新连接
如果你的应用请求处理逻辑耗时很长(比如调用外部接口超时、数据库查询慢),Tomcat的线程池(默认maxThreads=200)可能会被占满。虽然TCP连接可能已经完成握手,但因为没有可用线程处理请求,客户端会感觉连接“没建立”——你可以再确认下Wireshark抓包的握手阶段状态是否完成。
解决方法:
- 调整线程池参数:
server.tomcat.max-threads=500 server.tomcat.min-spare-threads=100 server.tomcat.max-queue-capacity=1000 - 排查应用的慢请求,比如用Spring Boot Actuator的
/actuator/threaddump接口查看阻塞线程,优化耗时的业务逻辑。
4. 自定义Tomcat配置出错
如果你的代码里自定义了TomcatServletWebServerFactory来配置Connector,一定要检查有没有误设连接限制参数。比如不小心把setMaxConnections(1)或者setAcceptCount(0)写进去,那肯定只能处理一个连接。
检查方法:
查看你的配置类,比如:
@Bean public TomcatServletWebServerFactory tomcatServletWebServerFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addConnectorCustomizers(connector -> { // 这里要确认没有错误的连接限制配置 connector.setPort(8081); // 确保用的是NIO模式,BIO模式的并发能力弱很多 connector.setProtocol("org.apache.coyote.http11.Http11NioProtocol"); }); return factory; }
5. 网络或客户端侧限制
最后,再确认下网络链路和客户端的问题:
- 在服务器端用
tcpdump抓8081端口的包,看是否收到第二个连接的SYN包。如果没收到,说明是客户端没发出来,或者中间网络设备(路由器、防火墙)拦截了;如果收到了但服务器没回复ACK,那还是回到服务器端的配置问题。 - 检查客户端操作系统的并发连接限制,比如Windows下的TCP连接数限制,或者客户端程序本身的连接池配置错误。
排查步骤总结
- 用
tcpdump在服务器端确认是否收到第二个连接的SYN包; - 检查Tomcat的
maxConnections、acceptCount和线程池参数; - 调整操作系统的TCP栈参数;
- 排查自定义Tomcat配置和应用慢请求;
- 验证网络链路和客户端限制。
内容的提问来源于stack exchange,提问作者Igor_M




