Skip to content

Commit 0c9015f

Browse files
committed
Merge pull request #6571 from herau:master
* pr/6571: Polish contribution Manage Tomcat queued connections
2 parents d5b2f67 + ab2a257 commit 0c9015f

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
* @author Eddú Meléndez
8787
* @author Quinten De Swaef
8888
* @author Venil Noronha
89+
* @author Aurélien Leboulanger
8990
*/
9091
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
9192
public class ServerProperties
@@ -656,6 +657,19 @@ public static class Tomcat {
656657
*/
657658
private Charset uriEncoding;
658659

660+
/**
661+
* Maximum number of connections that the server will accept and process
662+
* at any given time. Once the limit has been reached, the operating system
663+
* may still accept connections based on the "acceptCount" property.
664+
*/
665+
private int maxConnections = 0;
666+
667+
/**
668+
* Maximum queue length for incoming connection requests when all possible
669+
* request processing threads are in use.
670+
*/
671+
private int acceptCount = 0;
672+
659673
public int getMaxThreads() {
660674
return this.maxThreads;
661675
}
@@ -748,6 +762,22 @@ public void setUriEncoding(Charset uriEncoding) {
748762
this.uriEncoding = uriEncoding;
749763
}
750764

765+
public int getMaxConnections() {
766+
return this.maxConnections;
767+
}
768+
769+
public void setMaxConnections(int maxConnections) {
770+
this.maxConnections = maxConnections;
771+
}
772+
773+
public int getAcceptCount() {
774+
return this.acceptCount;
775+
}
776+
777+
public void setAcceptCount(int acceptCount) {
778+
this.acceptCount = acceptCount;
779+
}
780+
751781
void customizeTomcat(ServerProperties serverProperties,
752782
TomcatEmbeddedServletContainerFactory factory) {
753783
if (getBasedir() != null) {
@@ -782,6 +812,40 @@ void customizeTomcat(ServerProperties serverProperties,
782812
if (this.redirectContextRoot != null) {
783813
customizeRedirectContextRoot(factory, this.redirectContextRoot);
784814
}
815+
if (this.maxConnections > 0) {
816+
customizeMaxConnections(factory);
817+
}
818+
if (this.acceptCount > 0) {
819+
customizeAcceptCount(factory);
820+
}
821+
}
822+
823+
private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) {
824+
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
825+
826+
@Override
827+
public void customize(Connector connector) {
828+
ProtocolHandler handler = connector.getProtocolHandler();
829+
if (handler instanceof AbstractProtocol) {
830+
AbstractProtocol protocol = (AbstractProtocol) handler;
831+
protocol.setBacklog(Tomcat.this.acceptCount);
832+
}
833+
}
834+
});
835+
}
836+
837+
private void customizeMaxConnections(TomcatEmbeddedServletContainerFactory factory) {
838+
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
839+
840+
@Override
841+
public void customize(Connector connector) {
842+
ProtocolHandler handler = connector.getProtocolHandler();
843+
if (handler instanceof AbstractProtocol) {
844+
AbstractProtocol protocol = (AbstractProtocol) handler;
845+
protocol.setMaxConnections(Tomcat.this.maxConnections);
846+
}
847+
}
848+
});
785849
}
786850

787851
private void customizeConnectionTimeout(

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.catalina.Context;
3333
import org.apache.catalina.Valve;
3434
import org.apache.catalina.valves.RemoteIpValve;
35+
import org.apache.coyote.AbstractProtocol;
3536
import org.junit.Before;
3637
import org.junit.Test;
3738
import org.mockito.ArgumentCaptor;
@@ -435,6 +436,34 @@ public void customTomcatRemoteIpValve() throws Exception {
435436
assertThat(remoteIpValve.getInternalProxies()).isEqualTo("192.168.0.1");
436437
}
437438

439+
@Test
440+
public void customTomcatAcceptCount() {
441+
Map<String, String> map = new HashMap<String, String>();
442+
map.put("server.tomcat.accept-count", "10");
443+
bindProperties(map);
444+
445+
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
446+
this.properties.customize(container);
447+
TomcatEmbeddedServletContainer embeddedContainer =
448+
(TomcatEmbeddedServletContainer) container.getEmbeddedServletContainer();
449+
assertThat(((AbstractProtocol) embeddedContainer.getTomcat().getConnector()
450+
.getProtocolHandler()).getBacklog()).isEqualTo(10);
451+
}
452+
453+
@Test
454+
public void customTomcatMaxConnections() {
455+
Map<String, String> map = new HashMap<String, String>();
456+
map.put("server.tomcat.max-connections", "5");
457+
bindProperties(map);
458+
459+
TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory();
460+
this.properties.customize(container);
461+
TomcatEmbeddedServletContainer embeddedContainer =
462+
(TomcatEmbeddedServletContainer) container.getEmbeddedServletContainer();
463+
assertThat(((AbstractProtocol) embeddedContainer.getTomcat().getConnector()
464+
.getProtocolHandler()).getMaxConnections()).isEqualTo(5);
465+
}
466+
438467
@Test
439468
public void defaultUseForwardHeadersUndertow() throws Exception {
440469
UndertowEmbeddedServletContainerFactory container = spy(

spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ content into your application; rather pick only the properties that you need.
193193
server.ssl.trust-store-password= # Password used to access the trust store.
194194
server.ssl.trust-store-provider= # Provider for the trust store.
195195
server.ssl.trust-store-type= # Type of the trust store.
196+
server.tomcat.accept-count= # Maximum queue length for incoming connection requests when all possible request processing threads are in use.
196197
server.tomcat.accesslog.directory=logs # Directory in which log files are created. Can be relative to the tomcat base dir or absolute.
197198
server.tomcat.accesslog.enabled=false # Enable access log.
198199
server.tomcat.accesslog.pattern=common # Format pattern for access logs.
@@ -208,6 +209,7 @@ content into your application; rather pick only the properties that you need.
208209
172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|\\
209210
172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|\\
210211
172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3} # regular expression matching trusted IP addresses.
212+
server.tomcat.max-connections= # Maximum number of connections that the server will accept and process at any given time.
211213
server.tomcat.max-threads=0 # Maximum amount of worker threads.
212214
server.tomcat.min-spare-threads=0 # Minimum amount of worker threads.
213215
server.tomcat.port-header=X-Forwarded-Port # Name of the HTTP header used to override the original port value.

0 commit comments

Comments
 (0)