I am unable to configure the maxIdleTime for Tomcat server worker threads.

Have tried a couple of ways but with no success. The thread min and max size is configured via application properties. I am able to configure acceptor thread count via TomcatServletWebServerFactoryl Have tried some similar configuration via accessing the connector executor but no success. For example: ((StandardThreadExecutor) ((AbstractHttp11Protocol<?>) connector .getProtocolHandler()).getExecutor()).setMaxIdleTime(24 * 3600 * 1000)

Running latest Spring boot 2.1.4.

This case is connected to #9560 since the the reason I want to configure the maxIdleTime is to ba able to have an low min-spare-threads and a high maxIdleTime, so that for the service port it will have many spare threads in the pool (since the high maxIdleTime) but for the management port it will only use a few since there will never be many simultaneous requests.

Comment From: wilkinsona

Tomcat doesn't allow tuning of the keep alive time without configuring a custom executor. If Tomcat is left to create the executor (the default behaviour) it hard-codes the keep alive time as 60 seconds:

public void createExecutor() {
    internalExecutor = true;
    TaskQueue taskqueue = new TaskQueue();
    TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
    taskqueue.setParent( (ThreadPoolExecutor) executor);
}

Given Tomcat's current capabilities, your best option is probably to use a TomcatConnectorCustomizer to set the Executor on the ProtocolHandler of the Connector. If you'd like Tomcat to be more configurable in this area, please open a Tomcat issue to see if the keep alive time could be made configurable. If that change is made in Tomcat, we can re-open this issue and consider providing an application property for it.

Comment From: vilhelm-persson-viper

Hi The maxIdleTime is already a parameter that is configurable in Tomcat See https://tomcat.apache.org/tomcat-9.0-doc/config/executor.html#Standard_Implementation

Comment From: wilkinsona

Embedded Tomcat does not use a StandardThreadExecutor by default, that's why the endpoint creates its own Executor as shown in the code I linked to above. The ability to configure the keep alive time is missing from AbstractEndpoint and AbstractProtocol (they have setters for minSpareThreads and maxThreads which Boot already uses).

Comment From: RoySunnySean007

Hi @wilkinsona ,

Thanks for providing above comment. My problem is first busy threads goes up to max threads (800), then busy threads goes only to 10, but after 20+ minutes, currentThreadCount is still 800. Per my understanding, if threads is idle for 60 seconds, it will die. Could u please kindly help to have a look? Thanks!

Spring boot version: 1.5 Busy threads: tomcat_threadpool_currentthreadsbusy CurrentThreadsCount: tomcat_threadpool_currentthreadcount MinSpareThreads: tomcat_threadpool_minsparethreads

SpringBoot Unable to configure maxIdleTime for Tomcat server worker threads

Thanks, Roy

Comment From: wilkinsona

@RoySunnySean007 Given that Boot isn't involved in the configuration of the max idle time, the problem you are seeing is more likely to be a Tomcat problem than a Spring Boot problem. If you're looking for some guidance on how Tomcat behaves or think you may have found a bug, the Tomcat users mailing list is a good place to ask.

Also, please note that Spring Boot 1.5 is now end-of-life and you should upgrade to 2.1.x or 2.2.x.

Comment From: RoySunnySean007

Thx @wilkinsona ! Let me check if it will be resolved in Sprint Boot 2.x.

Comment From: ChristopherSchultz

FYI this is all based upon java.util.concurrent.ThreadPoolExecutor. So if the threads aren't retiring when you think they should, it's the behavior of that Java class that you don't like.

Comment From: ChristopherSchultz

As for configuring the thread timeout, you ought to be able to instantiate your own org.apache.tomcat.util.threads.ThreadPoolExecutor object and set it on the protocol handler. Then you can pick your own timeouts, etc.

Comment From: yinghuzhu

@RoySunnySean007 did you resolve this issue, I have the same problem. My SpringBoot version is 2.1.6