diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index c719cf0db215..782e2b6c0241 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -87,6 +87,7 @@ * @author Eddú Meléndez * @author Quinten De Swaef * @author Venil Noronha + * @author Aurélien Leboulanger */ @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true) public class ServerProperties @@ -657,6 +658,19 @@ public static class Tomcat { */ private Charset uriEncoding; + /** + * Maximum amount of connections accept and process. + *

Once the limit has been reached, + * the operating system may still accept connections based on the @link{acceptCount} setting.

+ */ + private int maxConnections = 0; + + /** + * Maximum queue length for incoming connection requests when all possible request processing threads are in use. + * Any requests received when the queue is full will be refused. + */ + private int acceptCount = 0; + public int getMaxThreads() { return this.maxThreads; } @@ -772,6 +786,22 @@ public void setUriEncoding(Charset uriEncoding) { this.uriEncoding = uriEncoding; } + public int getMaxConnections() { + return this.maxConnections; + } + + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + public int getAcceptCount() { + return this.acceptCount; + } + + public void setAcceptCount(int acceptCount) { + this.acceptCount = acceptCount; + } + void customizeTomcat(ServerProperties serverProperties, TomcatEmbeddedServletContainerFactory factory) { if (getBasedir() != null) { @@ -806,6 +836,40 @@ void customizeTomcat(ServerProperties serverProperties, if (this.redirectContextRoot != null) { customizeRedirectContextRoot(factory, this.redirectContextRoot); } + if (this.maxConnections > 0) { + customizeMaxConnections(factory); + } + if (this.acceptCount > 0) { + customizeAcceptCount(factory); + } + } + + private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) { + factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { + + @Override + public void customize(Connector connector) { + ProtocolHandler handler = connector.getProtocolHandler(); + if (handler instanceof AbstractProtocol) { + AbstractProtocol protocol = (AbstractProtocol) handler; + protocol.setBacklog(Tomcat.this.acceptCount); + } + } + }); + } + + private void customizeMaxConnections(TomcatEmbeddedServletContainerFactory factory) { + factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { + + @Override + public void customize(Connector connector) { + ProtocolHandler handler = connector.getProtocolHandler(); + if (handler instanceof AbstractProtocol) { + AbstractProtocol protocol = (AbstractProtocol) handler; + protocol.setMaxConnections(Tomcat.this.maxConnections); + } + } + }); } private void customizeConnectionTimeout( diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java index 0db14c7cf96c..73ad502405fc 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java @@ -321,6 +321,22 @@ public void testCustomizeTomcatMinSpareThreads() throws Exception { assertThat(this.properties.getTomcat().getMinSpareThreads()).isEqualTo(10); } + @Test + public void testCustomizeTomcatAcceptCount() throws Exception { + Map map = new HashMap(); + map.put("server.tomcat.accept-count", "10"); + bindProperties(map); + assertThat(this.properties.getTomcat().getAcceptCount()).isEqualTo(10); + } + + @Test + public void testCustomizeTomcatMaxConnections() throws Exception { + Map map = new HashMap(); + map.put("server.tomcat.max-connections", "5"); + bindProperties(map); + assertThat(this.properties.getTomcat().getMaxConnections()).isEqualTo(5); + } + @Test public void customizeTomcatDisplayName() throws Exception { Map map = new HashMap();