Reputation: 4237
I running a Spring Boot 2.6.x application (bundled with Tomcat 9.56.x) with the following configuration:
server.tomcat.accept-count = 100
server.tomcat.threads.max = 1000
server.tomcat.threads.min-spare = 10
on a machine with 16 CPU cores and 32GB of RAM
I testing a performance load of my server, during which I'm opening multiple (500) connections and each one sends a HTTP request every 1 second.
Expected behavior: tomcat will attempt to use as much threads as possible in order to maximize a throughput.
Actual behavior: tomcat always stick to 10 threads (which are configured by "min-spare") and never adding threads above that configured amount. I know that by observing its JMX endpoint (currentThreadCount is always 10). This is despite that it definitely not able to process all requests in time, since I have growing amount of pending requests in my client.
Does anyone can explain me such behavior? Based on what Tomcat (the NIO thread pool) supposed to decide whether to add threads?
Upvotes: 0
Views: 2819
Reputation: 4237
Turns out the issue was in my client.
For issuing requests, I was using RestTemplate which internally was using HttpClient. Well, HttpClient internally managing connections and by default it has ridiculously low limits configured - max 20 concurrent connections...
I solved the issue by configuring PoolingHttpClientConnectionManager (which supposed to deliver better throughput in multi-threaded environment) and increased limits:
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
PoolingHttpClientConnectionManager connManager
= new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(10000);
connManager.setDefaultMaxPerRoute(10000);
clientBuilder.setConnectionManager(connManager);
HttpClient httpClient = clientBuilder.build();
After doing that, I greatly increased issued requests per second which made Tomcat to add new threads - as expected
Upvotes: 1