Skip to content

Commit 6b35e3a

Browse files
committed
Manage Tomcat queued connections
Adding two tomcat server properties: - server.tomcat.accept-count - server.tomcat.max-connections Fixes gh-6433
1 parent f38bd7a commit 6b35e3a

File tree

2 files changed

+76
-14
lines changed

2 files changed

+76
-14
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
* @author Eddú Meléndez
8888
* @author Quinten De Swaef
8989
* @author Venil Noronha
90+
* @author Aurélien Leboulanger
9091
*/
9192
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
9293
public class ServerProperties
@@ -643,7 +644,7 @@ public static class Tomcat {
643644

644645
/**
645646
* Maximum size in bytes of the HTTP message header.
646-
*/
647+
*/
647648
private int maxHttpHeaderSize = 0; // bytes
648649

649650
/**
@@ -657,6 +658,19 @@ public static class Tomcat {
657658
*/
658659
private Charset uriEncoding;
659660

661+
/**
662+
* Maximum amount of connections accept and process.
663+
* <p>Once the limit has been reached,
664+
* the operating system may still accept connections based on the @link{acceptCount} setting.</p>
665+
*/
666+
private int maxConnections = 0;
667+
668+
/**
669+
* Maximum queue length for incoming connection requests when all possible request processing threads are in use.
670+
* Any requests received when the queue is full will be refused. The default value is 100.
671+
*/
672+
private int acceptCount = 100;
673+
660674
public int getMaxThreads() {
661675
return this.maxThreads;
662676
}
@@ -772,6 +786,22 @@ public void setUriEncoding(Charset uriEncoding) {
772786
this.uriEncoding = uriEncoding;
773787
}
774788

789+
public int getMaxConnections() {
790+
return this.maxConnections;
791+
}
792+
793+
public void setMaxConnections(int maxConnections) {
794+
this.maxConnections = maxConnections;
795+
}
796+
797+
public int getAcceptCount() {
798+
return this.acceptCount;
799+
}
800+
801+
public void setAcceptCount(int acceptCount) {
802+
this.acceptCount = acceptCount;
803+
}
804+
775805
void customizeTomcat(ServerProperties serverProperties,
776806
TomcatEmbeddedServletContainerFactory factory) {
777807
if (getBasedir() != null) {
@@ -799,24 +829,40 @@ void customizeTomcat(ServerProperties serverProperties,
799829
if (getUriEncoding() != null) {
800830
factory.setUriEncoding(getUriEncoding());
801831
}
802-
if (serverProperties.getConnectionTimeout() != null) {
803-
customizeConnectionTimeout(factory,
804-
serverProperties.getConnectionTimeout());
832+
if (this.maxConnections > 0) {
833+
customizeMaxConnections(factory);
805834
}
806-
if (this.redirectContextRoot != null) {
807-
customizeRedirectContextRoot(factory, this.redirectContextRoot);
835+
if (this.acceptCount != 100) {
836+
customizeAcceptCount(factory);
808837
}
809838
}
810839

811-
private void customizeConnectionTimeout(
812-
TomcatEmbeddedServletContainerFactory factory, int connectionTimeout) {
813-
for (Connector connector : factory.getAdditionalTomcatConnectors()) {
814-
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
815-
AbstractProtocol<?> handler = (AbstractProtocol<?>) connector
816-
.getProtocolHandler();
817-
handler.setConnectionTimeout(connectionTimeout);
840+
private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) {
841+
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
842+
843+
@Override
844+
public void customize(Connector connector) {
845+
ProtocolHandler handler = connector.getProtocolHandler();
846+
if (handler instanceof AbstractProtocol) {
847+
AbstractProtocol protocol = (AbstractProtocol) handler;
848+
protocol.setBacklog(Tomcat.this.acceptCount);
849+
}
818850
}
819-
}
851+
});
852+
}
853+
854+
private void customizeMaxConnections(TomcatEmbeddedServletContainerFactory factory) {
855+
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
856+
857+
@Override
858+
public void customize(Connector connector) {
859+
ProtocolHandler handler = connector.getProtocolHandler();
860+
if (handler instanceof AbstractProtocol) {
861+
AbstractProtocol protocol = (AbstractProtocol) handler;
862+
protocol.setMaxConnections(Tomcat.this.maxConnections);
863+
}
864+
}
865+
});
820866
}
821867

822868
private void customizeBackgroundProcessorDelay(

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,22 @@ public void testCustomizeTomcatMinSpareThreads() throws Exception {
321321
assertThat(this.properties.getTomcat().getMinSpareThreads()).isEqualTo(10);
322322
}
323323

324+
@Test
325+
public void testCustomizeTomcatAcceptCount() throws Exception {
326+
Map<String, String> map = new HashMap<String, String>();
327+
map.put("server.tomcat.accept-count", "10");
328+
bindProperties(map);
329+
assertThat(this.properties.getTomcat().getAcceptCount()).isEqualTo(10);
330+
}
331+
332+
@Test
333+
public void testCustomizeTomcatMaxConnections() throws Exception {
334+
Map<String, String> map = new HashMap<String, String>();
335+
map.put("server.tomcat.max-connections", "5");
336+
bindProperties(map);
337+
assertThat(this.properties.getTomcat().getMaxConnections()).isEqualTo(5);
338+
}
339+
324340
@Test
325341
public void customizeTomcatDisplayName() throws Exception {
326342
Map<String, String> map = new HashMap<String, String>();

0 commit comments

Comments
 (0)