Add properties for Jetty threadpool

See gh-17871
This commit is contained in:
HaiTao Zhang 2019-08-14 16:22:54 -07:00 committed by Madhura Bhave
parent 09b690b3c9
commit 1024d74742
4 changed files with 128 additions and 0 deletions

View File

@ -62,6 +62,7 @@ import org.springframework.util.unit.DataSize;
* @author Andrew McGhie
* @author Rafiullah Hamedy
* @author Dirk Deyne
* @author HaiTao Zhang
* @since 1.0.0
*/
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
@ -905,6 +906,21 @@ public class ServerProperties {
*/
private Integer selectors = -1;
/**
* Maximum amount of threads.
*/
private Integer maxThreads = 200;
/**
* Minimum amount of threads.
*/
private Integer minThreads = 8;
/**
* Maximum thread idle time.
*/
private Integer idleTimeout = 60000;
public Accesslog getAccesslog() {
return this.accesslog;
}
@ -933,6 +949,30 @@ public class ServerProperties {
this.selectors = selectors;
}
public void setMinThreads(Integer minThreads) {
this.minThreads = minThreads;
}
public Integer getMinThreads() {
return this.minThreads;
}
public void setMaxThreads(Integer maxThreads) {
this.maxThreads = maxThreads;
}
public Integer getMaxThreads() {
return this.maxThreads;
}
public void setIdleTimeout(Integer idleTimeout) {
this.idleTimeout = idleTimeout;
}
public Integer getIdleTimeout() {
return this.idleTimeout;
}
/**
* Jetty access log properties.
*/

View File

@ -29,6 +29,8 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.cloud.CloudPlatform;
@ -46,6 +48,7 @@ import org.springframework.util.unit.DataSize;
*
* @author Brian Clozel
* @author Phillip Webb
* @author HaiTao Zhang
* @since 2.0.0
*/
public class JettyWebServerFactoryCustomizer
@ -78,6 +81,12 @@ public class JettyWebServerFactoryCustomizer
.addServerCustomizers(new MaxHttpHeaderSizeCustomizer(maxHttpHeaderSize)));
propertyMapper.from(jettyProperties::getMaxHttpPostSize).asInt(DataSize::toBytes).when(this::isPositive)
.to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory, maxHttpPostSize));
propertyMapper.from(jettyProperties::getMaxThreads).when(this::isPositive)
.to((maxThreads) -> customizeMaxThreads(factory, maxThreads));
propertyMapper.from(jettyProperties::getMinThreads).when(this::isPositive)
.to((minThreads) -> customizeMinThreads(factory, minThreads));
propertyMapper.from(jettyProperties::getIdleTimeout).when(this::isPositive)
.to((idleTimeout) -> customizeIdleTimeout(factory, idleTimeout));
propertyMapper.from(properties::getConnectionTimeout).whenNonNull()
.to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout));
propertyMapper.from(jettyProperties::getAccesslog).when(ServerProperties.Jetty.Accesslog::isEnabled)
@ -131,6 +140,33 @@ public class JettyWebServerFactoryCustomizer
});
}
private void customizeMaxThreads(ConfigurableJettyWebServerFactory factory, int maxThreads) {
factory.addServerCustomizers((connector) -> {
ThreadPool threadPool = connector.getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
((QueuedThreadPool) threadPool).setMaxThreads(maxThreads);
}
});
}
private void customizeMinThreads(ConfigurableJettyWebServerFactory factory, int minThreads) {
factory.addServerCustomizers((connector) -> {
ThreadPool threadPool = connector.getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
((QueuedThreadPool) threadPool).setMinThreads(minThreads);
}
});
}
private void customizeIdleTimeout(ConfigurableJettyWebServerFactory factory, int idleTimeout) {
factory.addServerCustomizers((connector) -> {
ThreadPool threadPool = connector.getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
((QueuedThreadPool) threadPool).setIdleTimeout(idleTimeout);
}
});
}
private void customizeAccessLog(ConfigurableJettyWebServerFactory factory,
ServerProperties.Jetty.Accesslog properties) {
factory.addServerCustomizers((server) -> {

View File

@ -74,6 +74,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Quinten De Swaef
* @author Venil Noronha
* @author Andrew McGhie
* @author HaiTao Zhang
*/
class ServerPropertiesTests {
@ -218,6 +219,24 @@ class ServerPropertiesTests {
assertThat(this.properties.getJetty().getSelectors()).isEqualTo(10);
}
@Test
void testCustomizeJettyMaxThreads() {
bind("server.jetty.max-threads", "10");
assertThat(this.properties.getJetty().getMaxThreads()).isEqualTo(10);
}
@Test
void testCustomizeJettyMinThreads() {
bind("server.jetty.min-threads", "10");
assertThat(this.properties.getJetty().getMinThreads()).isEqualTo(10);
}
@Test
void testCustomizeJettyIdleTimeout() {
bind("server.jetty.idle-timeout", "10");
assertThat(this.properties.getJetty().getIdleTimeout()).isEqualTo(10);
}
@Test
void testCustomizeUndertowServerOption() {
bind("server.undertow.options.server.ALWAYS_SET_KEEP_ALIVE", "true");

View File

@ -27,6 +27,8 @@ import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConfiguration.ConnectionFactory;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.RequestLogWriter;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -49,6 +51,7 @@ import static org.mockito.Mockito.verify;
*
* @author Brian Clozel
* @author Phillip Webb
* @author HaiTao Zhang
*/
class JettyWebServerFactoryCustomizerTests {
@ -112,6 +115,36 @@ class JettyWebServerFactoryCustomizerTests {
assertThat(logWriter.isAppend()).isFalse();
}
@Test
void maxThreadsCanBeCustomized() throws IOException {
bind("server.jetty.max-threads=100");
JettyWebServer server = customizeAndGetServer();
ThreadPool threadPool = server.getServer().getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
assertThat(((QueuedThreadPool) threadPool).getMaxThreads()).isEqualTo(100);
}
}
@Test
void minThreadsCanBeCustomized() throws IOException {
bind("server.jetty.min-threads=100");
JettyWebServer server = customizeAndGetServer();
ThreadPool threadPool = server.getServer().getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
assertThat(((QueuedThreadPool) threadPool).getMinThreads()).isEqualTo(100);
}
}
@Test
void idleTimeoutCanBeCustomized() throws IOException {
bind("server.jetty.idle-timeout=100");
JettyWebServer server = customizeAndGetServer();
ThreadPool threadPool = server.getServer().getThreadPool();
if (threadPool instanceof QueuedThreadPool) {
assertThat(((QueuedThreadPool) threadPool).getIdleTimeout()).isEqualTo(100);
}
}
private CustomRequestLog getRequestLog(JettyWebServer server) {
RequestLog requestLog = server.getServer().getRequestLog();
assertThat(requestLog).isInstanceOf(CustomRequestLog.class);