JMeter 和 Spring Boot Web 服务器之间的并发线程数限制为 2000 个

问题描述 投票:0回答:1

我观察到 JMeter 和简单的 Spring Boot Web 服务器之间存在奇怪的行为,它们都在我的本地计算机上运行。

我在多个线程中同时运行一个简单的 Web 服务调用。当我将 JMeter 设置为运行 2000 个线程时,一切正常。当我将其设置为 2001 时,大多数请求都会失败。

2000 是一个什么样的神奇数字?哪些设置导致了这个限制?

配置:

  • Windows 11
  • Java 21
  • Spring Boot 3.2.0-RC1(但与 3.1.5 的行为相同)
  • 阿帕奇 JMeter 5.6.2
  • 16核CPU
  • 64GB内存

我发现了一个听起来类似的问题JMeter线程用户限制 - 并发执行5000个线程但它似乎没有涵盖相同的问题。

Spring Boot代码:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/person")
public class PersonController {
    @GetMapping
    public String getPerson() {
        return "John";
    }
}

应用程序属性:

server.port=9001
server.tomcat.threads.max=10000
server.tomcat.max-connections=10000
server.tomcat.accept-count=10000

Spring Boot启动日志:

MyApplication                            : Starting MyApplication using Java 21 with PID 71328
MyApplication                            : No active profile set, falling back to 1 default profile: "default"
o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 9001 (http)
o.apache.catalina.core.StandardService   : Starting service [Tomcat]
o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.15]
o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 671 ms
o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 9001 (http) with context path ''
MyApplication                            : Started MyApplication in 1.302 seconds (process running for 1.812)
o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms

JMeter请求配置:

2000 个并发线程的 JMeter 结果:

2001 个并发线程的 JMeter 结果:

JMeter 将每个错误显示为

HttpHostConnectException
,并且调用似乎根本没有到达 Spring Boot 应用程序:

org.apache.http.conn.HttpHostConnectException: Connect to localhost:9001 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:156)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator.connect(HTTPHC4Impl.java:409)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:940)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:651)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:66)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1311)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1300)
    at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:651)
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:570)
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501)
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.net.ConnectException: Connection refused: connect
    at java.base/sun.nio.ch.Net.connect0(Native Method)
    at java.base/sun.nio.ch.Net.connect(Net.java:589)
    at java.base/sun.nio.ch.Net.connect(Net.java:578)
    at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
    at java.base/java.net.Socket.connect(Socket.java:751)
    at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    ... 19 more

java spring-boot concurrency jmeter performance-testing
1个回答
0
投票

这听起来像是您操作系统的网络配置问题,您可以尝试做的事情是:

  1. 增加 TCP/IP 的动态端口范围
  2. 减少 TcpTimedWaitDelay
  3. 增加TCP连接数

还有一些其他需要考虑的事情:

  • 总的来说,我不认为“2000”是一个神奇的数字,你可以尝试添加Active Threads Over Time监听器来查看最大在线用户数,我认为它小于2000。
  • 发送 2000 个请求不是您通常应该做的事情,我宁愿逐渐增加负载,即几分钟,然后让 2000 个用户再运行几分钟,这样您就能够关联负载随着响应时间的增加而增加,或者错误开始发生。
  • 将负载生成器和被测系统放在同一台机器上也不应该是您通常应该做的事情,因为您不太可能获得良好/有效的结果,因为 JMeter 和 Spring Boot 都会“争夺操作系统资源”并获胜表现得不够好。一般来说,您应该针对生产环境或其精确副本运行测试,您不能将测试结果从缩小的环境推断到更大的环境,因为需要考虑的变量太多。
© www.soinside.com 2019 - 2024. All rights reserved.