aboutsummaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-10-19 14:35:41 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-10-19 14:35:41 +0200
commite4915ba435f80ec2cec700c36533e97ccf40291a (patch)
tree07b3e3c05899492da4ed234096f1816d2e5fbf98 /config-model
parent96e57d962282f90b29a01dd188ae9ba1e26746d8 (diff)
Scale Jetty threadpool size with node resources
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/Container.java10
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java2
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java23
8 files changed, 67 insertions, 7 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 00c5f6e326f..e141826ba44 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -54,6 +54,7 @@ public class TestProperties implements ModelContext.Properties {
private ApplicationRoles applicationRoles;
private Quota quota = Quota.unlimited();
private boolean useAccessControlTlsHandshakeClientAuth;
+ private double jettyThreadpoolSizeFactor = 0.0;
@Override public boolean multitenant() { return multitenant; }
@Override public ApplicationId applicationId() { return applicationId; }
@@ -93,6 +94,7 @@ public class TestProperties implements ModelContext.Properties {
@Override public boolean tlsUseFSync() { return tlsUseFSync; }
@Override public String tlsCompressionType() { return tlsCompressionType; }
@Override public boolean useAccessControlTlsHandshakeClientAuth() { return useAccessControlTlsHandshakeClientAuth; }
+ @Override public double jettyThreadpoolSizeFactor() { return jettyThreadpoolSizeFactor; }
public TestProperties setJvmGCOptions(String gcOptions) {
jvmGCOptions = gcOptions;
@@ -144,6 +146,9 @@ public class TestProperties implements ModelContext.Properties {
this.queueSizeFactor = queueSizeFactor;
return this;
}
+
+ public TestProperties setJettyThreadpoolSizeFactor(double factor) { this.jettyThreadpoolSizeFactor = factor; return this; }
+
public TestProperties setApplicationId(ApplicationId applicationId) {
this.applicationId = applicationId;
return this;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
index 1d991721ea7..a7f5398c7b5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
@@ -88,7 +88,7 @@ public abstract class Container extends AbstractService implements
this.parent = parent;
this.retired = retired;
this.index = index;
- this.defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), isHostedVespa);
+ this.defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), containerClusterOrNull(parent), isHostedVespa);
if (getHttp() == null) {
addChild(defaultHttpServer);
}
@@ -390,8 +390,12 @@ public abstract class Container extends AbstractService implements
return containerCluster().isPresent() && containerCluster().get().rpcServerEnabled();
}
- private Optional<ContainerCluster> containerCluster() {
- return (parent instanceof ContainerCluster) ? Optional.of((ContainerCluster) parent) : Optional.empty();
+ protected Optional<ContainerCluster> containerCluster() {
+ return Optional.ofNullable(containerClusterOrNull(parent));
+ }
+
+ private static ContainerCluster containerClusterOrNull(AbstractConfigProducer producer) {
+ return producer instanceof ContainerCluster<?> ? (ContainerCluster<?>) producer : null;
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 4888add3253..57ebc215dfa 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -161,11 +161,14 @@ public abstract class ContainerCluster<CONTAINER extends Container>
private boolean deferChangesUntilRestart = false;
+ private double jettyThreadpoolSizeFactor;
+
public ContainerCluster(AbstractConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) {
super(parent, configSubId);
this.name = clusterId;
this.isHostedVespa = stateIsHosted(deployState);
this.zone = (deployState != null) ? deployState.zone() : Zone.defaultZone();
+ this.jettyThreadpoolSizeFactor = deployState.getProperties().jettyThreadpoolSizeFactor();
componentGroup = new ComponentGroup<>(this, "component");
@@ -639,4 +642,7 @@ public abstract class ContainerCluster<CONTAINER extends Container>
.max(); // Use highest vcpu as scale factor
}
+ public OptionalDouble jettyThreadpoolSizeFactor() {
+ return jettyThreadpoolSizeFactor > 0 ? OptionalDouble.of(jettyThreadpoolSizeFactor) : OptionalDouble.empty();
+ }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
index 98fde2e7859..8d55b424ad9 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
@@ -6,6 +6,7 @@ import com.yahoo.component.ComponentSpecification;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.osgi.provider.model.ComponentModel;
+import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.SimpleComponent;
import java.util.ArrayList;
@@ -20,16 +21,18 @@ import static com.yahoo.component.ComponentSpecification.fromString;
*/
public class JettyHttpServer extends SimpleComponent implements ServerConfig.Producer {
+ private final ContainerCluster<?> cluster;
private final boolean isHostedVespa;
private final List<ConnectorFactory> connectorFactories = new ArrayList<>();
- public JettyHttpServer(ComponentId id, boolean isHostedVespa) {
+ public JettyHttpServer(ComponentId id, ContainerCluster<?> cluster, boolean isHostedVespa) {
super(new ComponentModel(
new BundleInstantiationSpecification(id,
fromString("com.yahoo.jdisc.http.server.jetty.JettyHttpServer"),
fromString("jdisc_http_service"))
));
this.isHostedVespa = isHostedVespa;
+ this.cluster = cluster;
final FilterBindingsProviderComponent filterBindingsProviderComponent = new FilterBindingsProviderComponent(id);
addChild(filterBindingsProviderComponent);
inject(filterBindingsProviderComponent);
@@ -69,6 +72,17 @@ public class JettyHttpServer extends SimpleComponent implements ServerConfig.Pro
.remoteAddressHeaders(List.of("x-forwarded-for", "y-ra", "yahooremoteip", "client-ip"))
.remotePortHeaders(List.of("X-Forwarded-Port", "y-rp")));
}
+ configureJettyThreadpool(builder);
+ }
+
+ private void configureJettyThreadpool(ServerConfig.Builder builder) {
+ if (cluster == null) return;
+ double vcpu = cluster.vcpu().orElse(0);
+ double scaleFactor = cluster.jettyThreadpoolSizeFactor().orElse(0);
+ if (vcpu > 0 && scaleFactor > 0) {
+ int threads = Math.max(8, (int) Math.ceil(vcpu * scaleFactor));
+ builder.maxWorkerThreads(threads).minWorkerThreads(threads);
+ }
}
static ComponentModel providerComponentModel(final ComponentId parentId, String className) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
index 004539688e2..9b9ebedda6d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
@@ -56,7 +56,8 @@ public class HttpBuilder extends VespaDomBuilder.DomConfigProducerBuilder<Http>
Http http = new Http(filterChains);
http.getBindings().addAll(bindings);
- http.setHttpServer(new JettyHttpServerBuilder().build(deployState, ancestor, spec));
+ ApplicationContainerCluster cluster = getContainerCluster(ancestor).orElse(null);
+ http.setHttpServer(new JettyHttpServerBuilder(cluster).build(deployState, ancestor, spec));
if (accessControl != null) {
accessControl.configureHttpFilterChains(http);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
index cc9cd61df36..7f3c5f653aa 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
@@ -6,6 +6,7 @@ import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.text.XML;
import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder;
+import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.http.ConnectorFactory;
import com.yahoo.vespa.model.container.http.JettyHttpServer;
import org.w3c.dom.Element;
@@ -15,9 +16,15 @@ import org.w3c.dom.Element;
*/
public class JettyHttpServerBuilder extends VespaDomBuilder.DomConfigProducerBuilder<JettyHttpServer> {
+ private final ContainerCluster<?> cluster;
+
+ public JettyHttpServerBuilder(ContainerCluster<?> cluster) {
+ this.cluster = cluster;
+ }
+
@Override
protected JettyHttpServer doBuild(DeployState deployState, AbstractConfigProducer ancestor, Element http) {
- JettyHttpServer jettyHttpServer = new JettyHttpServer(new ComponentId("jdisc-jetty"), deployState.isHosted());
+ JettyHttpServer jettyHttpServer = new JettyHttpServer(new ComponentId("jdisc-jetty"), cluster, deployState.isHosted());
for (Element serverSpec: XML.getChildren(http, "server")) {
ConnectorFactory connectorFactory = new JettyConnectorBuilder().build(deployState, ancestor, serverSpec);
jettyHttpServer.addConnector(connectorFactory);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index 6fd1c9b35fb..37dd97a49b1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -360,7 +360,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
cluster.setHttp(new Http(new FilterChains(cluster)));
}
if(cluster.getHttp().getHttpServer().isEmpty()) {
- JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), cluster.isHostedVespa());
+ JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), cluster, cluster.isHostedVespa());
cluster.getHttp().setHttpServer(defaultHttpServer);
defaultHttpServer.addConnector(new ConnectorFactory("SearchServer", Defaults.getDefaults().vespaWebServicePort()));
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index 3515efb7bc1..80fc713d69a 100755
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -18,6 +18,7 @@ import com.yahoo.config.provision.Zone;
import com.yahoo.container.di.config.PlatformBundlesConfig;
import com.yahoo.container.handler.ThreadPoolProvider;
import com.yahoo.container.handler.ThreadpoolConfig;
+import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.search.config.QrStartConfig;
import com.yahoo.vespa.model.Host;
import com.yahoo.vespa.model.HostResource;
@@ -280,6 +281,28 @@ public class ContainerClusterTest {
}
@Test
+ public void jetty_threadpool_scales_with_node_resources() {
+ HostProvisionerWithCustomRealResource hostProvisioner = new HostProvisionerWithCustomRealResource();
+ MockRoot root = new MockRoot(
+ "foo",
+ new DeployState.Builder()
+ .properties(new TestProperties().setJettyThreadpoolSizeFactor(4).setHostedVespa(true))
+ .applicationPackage(new MockApplicationPackage.Builder().build())
+ .modelHostProvisioner(hostProvisioner)
+ .build());
+ ApplicationContainerCluster cluster = createContainerCluster(root, false);
+ HostResource hostResource = new HostResource(
+ new Host(null, "host-c1"),
+ hostProvisioner.allocateHost("host-c1"));
+ addContainerWithHostResource(root.deployLogger(), cluster, "c1", hostResource);
+ root.freezeModelTopology();
+
+ ServerConfig cfg = root.getConfig(ServerConfig.class, "container0/c1/DefaultHttpServer");
+ assertEquals(16, cfg.maxWorkerThreads());
+ assertEquals(16, cfg.minWorkerThreads());
+ }
+
+ @Test
public void requireThatRoutingProviderIsDisabledForNonHosted() {
DeployState state = new DeployState.Builder().properties(new TestProperties().setHostedVespa(false)).build();
MockRoot root = new MockRoot("foo", state);