Hi 👋

I was going through the server properties for Tomcat and I couldn't find the keepAliveTimeout and maxKeepAliveRequests.

At the moment we configure them programmatically using a customizer but I'm wondering if it'd be possible/useful for Spring Boot to expose them.

I also found this comment. In our case we have L7 load balancing and we set maxKeepAliveRequests to -1 (i.e. unlimited) with a keepAliveTimeout which is higher than the connection timeout.

Comment From: ywei2017

Wondering of the sameting. @nikos912000 , did you get some answers?

Comment From: philwebb

@nikmanzotti Would you be able to share your customizer code?

Comment From: nikos912000

Hi @philwebb

Sure, my class implements the TomcatConnectorCustomizer and the customize method is as follows:

public void customize(final Connector connector) {
        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();

        protocol.setExecutor(executor);
        protocol.setMaxThreads(maxThreads);
        protocol.setMaxConnections(maxConnections);
        protocol.setAcceptCount(acceptCount);
        protocol.setConnectionTimeout(connectionTimeout);
        protocol.setKeepAliveTimeout(keepAliveTimeout);
        protocol.setMaxKeepAliveRequests(maxKeepAliveRequests);
        protocol.setProcessorCache(processorCache);
}

Comment From: mlubavin-vg

The reason this would be useful to us, is because when using Spring Cloud Gateway, with default netty httpclient that does connection pooling and keepalive, we see reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response

At first, adding spring.cloud.gateway.httpclient.pool.max-idle-time: 55s helped us avoid this from Tomcat closing connections due to being idle.

But now we are seeing some connections get closed by Tomcat due to hitting maxKeepAliveRequests. And unfortunately there is no setting on the Netty HttpClient to set a max number of requests on one connection before throwing it away. We can only set spring.cloud.gateway.httpclient.pool.max-life-time but that doesn't help since we can have 100 requests go through in under 30 seconds.

We will now use the TomcatCustomizer, but it would be really nice to be able to set this in spring boot settings

Comment From: philwebb

Thanks the for feedback. We agree that adding these additional properties would be worthwhile. Targeted to 2.x but also flagged as ideal-for-contribution in case anyone from the community is interested in submitting a PR.

Comment From: parviz-93

Hi, I would be glad to work on this issue.

Comment From: scottfrederick

@parviz-93 I've assigned the issue to you. Please let us know if you have any questions.

Comment From: mlubavin

Hello, @parviz-93 if you haven't yet implemented this, I would like to offer my implementation. I had time today and wanted to try out contributing to spring-boot for the first time. Here is my PR: https://github.com/spring-projects/spring-boot/pull/25805

Comment From: wilkinsona

@mlubavin Thanks, but it has only been three days.

@parviz-93 Please carry on with working on this and let us know if you have any questions.

Comment From: parviz-93

@scottfrederick, @wilkinsona thanks. I actually finished several days ago, but there is a question on the property "keepAliveTimeout", that I left for the weekends.

The tomcat documentation said that in this field we can set -1 and when I use Duration class for more comfortable declaration but I can't set -1 for class Duration. In point of my view, we must have a possibility to set -1 for this field.

Can you please tell me how to get around this issue? so I could use "1ms" and "-1" for the "keepAliveTimeout". Maybe, i can use long/int

Comment From: wilkinsona

@parviz-93 Duration does support negative values so I think we should be able to us Duration for the property's type. Tomcat appears to treat any value or 0 of less as -1 so I think we can get the duration in milliseconds and pass that into Tomcat without a special case for -1.

Comment From: parviz-93

@wilkinsona Yes, you are right! I was wrong about Duration.

Comment From: snicoll

Closing in favor of PR #25815