Understanding Default Tomcat Settings in Spring Boot 2.7.10 and Tuning Connection Parameters
This article explains the default Tomcat configuration bundled with Spring Boot 2.7.10, details key parameters such as accept‑count, max‑connections, thread pool sizes and timeouts, shows how Tomcat’s internal threads work, provides sample YAML configurations and testing results, and offers practical tuning guidance for Java backend services.
Spring Boot 2.7.10 embeds Tomcat 9.0.73 with default settings: accept‑count 100, max‑connections 8192, min‑spare‑threads 10, max‑threads 200, connection‑timeout 20s, etc. The article lists these defaults and shows the corresponding server.tomcat YAML configuration.
server: tomcat: # Maximum queue length for incoming connections when all request processing threads are busy accept-count: 100 # Maximum number of connections the server will accept and process at any time max-connections: 8192 threads: # Minimum number of worker threads created at startup min-spare: 10 # Maximum number of worker threads (IO‑intensive workloads usually 10×CPU cores) max: 200 connection-timeout: 20000 keep-alive-timeout: 20000 max-keep-alive-requests: 100
The article then explains core parameters:
AcceptCount – the connection backlog, equivalent to the Linux somaxconn value.
MaxConnections – limits total simultaneous connections; once reached, new connections wait in the backlog.
MinSpareThread / MaxThread – Tomcat’s extended thread pool where tasks flow from min → max → queue → exception, differing from the standard JDK pool order.
MaxKeepAliveRequests – after this many requests on a persistent connection, Tomcat closes the socket.
ConnectionTimeout – idle time before the server closes an established connection.
KeepAliveTimeout – time to wait for the next HTTP request on a keep‑alive connection; -1 disables timeout.
Key internal components are described with code excerpts:
Acceptor – accepts socket connections and registers them with the poller.
public void run() {
while (!stopCalled) {
socket = endpoint.serverSocketAccept();
endpoint.setSocketOptions(socket);
// register socket with poller
}
}Poller – iterates over ready SelectionKey objects and dispatches them to the executor.
public void run() {
while (true) {
Iterator
iterator = selector.selectedKeys().iterator();
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
iterator.remove();
NioSocketWrapper socketWrapper = (NioSocketWrapper) sk.attachment();
if (socketWrapper != null) {
processKey(sk, socketWrapper);
executor.execute(new SocketProcessor(socketWrapper, SocketEvent));
}
}
}
}TomcatThreadPoolExecutor – a custom extension of java.util.concurrent.ThreadPoolExecutor that tracks submitted tasks and provides a forced queue insertion mechanism.
public void execute(Runnable command) {
submittedCount.incrementAndGet();
try {
super.execute(command);
} catch (RejectedExecutionException rx) {
if (super.getQueue() instanceof TaskQueue) {
TaskQueue queue = (TaskQueue) super.getQueue();
if (!queue.force(command, timeout, unit)) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException("threadPoolExecutor.queueFull");
}
} else {
submittedCount.decrementAndGet();
throw rx;
}
}
}The article provides a sample test configuration (e.g., accept-count: 3 , max-connections: 6 , min-spare: 2 , max: 3 ) and shows how to observe connection queues using ss -nltp and netstat . It demonstrates the behavior when the number of concurrent connections exceeds the configured limits, resulting in SYN‑RECV or SYN‑SENT states and client‑side timeouts.
Finally, the author adds a promotional note encouraging readers to like, share, and follow the author’s knowledge platform, offering additional premium content for a fee.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.