Externalize httpd and sshd thread computation
Move sshd.threads, httpd.maxThreads and database.poolLimit to separate class. This way default value of poolLimit can be dynamically computed based on two previously mentioned properties. Change-Id: I5167c4a42ed5e5a480d0ff4accba490dffa05fd4 Signed-off-by: Dariusz Luksza <dariusz@luksza.org>
This commit is contained in:
@@ -1404,7 +1404,8 @@ This limit must be several units higher than the total number of
|
|||||||
httpd and sshd threads as some request processing code paths may
|
httpd and sshd threads as some request processing code paths may
|
||||||
need multiple connections.
|
need multiple connections.
|
||||||
+
|
+
|
||||||
Default is 8.
|
Default is <<sshd.threads, sshd.threads>>
|
||||||
|
+ <<httpd.maxThreads, httpd.maxThreads>> + 2.
|
||||||
+
|
+
|
||||||
This setting only applies if
|
This setting only applies if
|
||||||
<<database.connectionPool,database.connectionPool>> is true.
|
<<database.connectionPool,database.connectionPool>> is true.
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.google.gerrit.pgm.http.jetty.HttpLog.HttpLogFactory;
|
|||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
|
import com.google.gerrit.server.config.ThreadSettingsConfig;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
@@ -127,11 +128,14 @@ public class JettyServer {
|
|||||||
private boolean reverseProxy;
|
private boolean reverseProxy;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
JettyServer(@GerritServerConfig final Config cfg, final SitePaths site,
|
JettyServer(@GerritServerConfig Config cfg,
|
||||||
final JettyEnv env, final HttpLogFactory httpLogFactory) {
|
ThreadSettingsConfig threadSettingsConfig,
|
||||||
|
SitePaths site,
|
||||||
|
JettyEnv env,
|
||||||
|
HttpLogFactory httpLogFactory) {
|
||||||
this.site = site;
|
this.site = site;
|
||||||
|
|
||||||
httpd = new Server(threadPool(cfg));
|
httpd = new Server(threadPool(cfg, threadSettingsConfig));
|
||||||
httpd.setConnectors(listen(httpd, cfg));
|
httpd.setConnectors(listen(httpd, cfg));
|
||||||
|
|
||||||
Handler app = makeContext(env, cfg);
|
Handler app = makeContext(env, cfg);
|
||||||
@@ -315,8 +319,8 @@ public class JettyServer {
|
|||||||
return site.resolve(path);
|
return site.resolve(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThreadPool threadPool(Config cfg) {
|
private ThreadPool threadPool(Config cfg, ThreadSettingsConfig threadSettingsConfig) {
|
||||||
int maxThreads = cfg.getInt("httpd", null, "maxthreads", 25);
|
int maxThreads = threadSettingsConfig.getHttpdMaxThreads();
|
||||||
int minThreads = cfg.getInt("httpd", null, "minthreads", 5);
|
int minThreads = cfg.getInt("httpd", null, "minthreads", 5);
|
||||||
int maxQueued = cfg.getInt("httpd", null, "maxqueued", 200);
|
int maxQueued = cfg.getInt("httpd", null, "maxqueued", 200);
|
||||||
int idleTimeout = (int)MILLISECONDS.convert(60, SECONDS);
|
int idleTimeout = (int)MILLISECONDS.convert(60, SECONDS);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import com.google.gerrit.common.SiteLibraryLoaderUtil;
|
|||||||
import com.google.gerrit.metrics.MetricMaker;
|
import com.google.gerrit.metrics.MetricMaker;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
|
import com.google.gerrit.server.config.ThreadSettingsConfig;
|
||||||
import com.google.gerrit.server.schema.DataSourceProvider;
|
import com.google.gerrit.server.schema.DataSourceProvider;
|
||||||
import com.google.gerrit.server.schema.DataSourceType;
|
import com.google.gerrit.server.schema.DataSourceType;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@@ -39,9 +40,10 @@ public class SiteLibraryBasedDataSourceProvider extends DataSourceProvider {
|
|||||||
SiteLibraryBasedDataSourceProvider(SitePaths site,
|
SiteLibraryBasedDataSourceProvider(SitePaths site,
|
||||||
@GerritServerConfig Config cfg,
|
@GerritServerConfig Config cfg,
|
||||||
MetricMaker metrics,
|
MetricMaker metrics,
|
||||||
|
ThreadSettingsConfig tsc,
|
||||||
DataSourceProvider.Context ctx,
|
DataSourceProvider.Context ctx,
|
||||||
DataSourceType dst) {
|
DataSourceType dst) {
|
||||||
super(cfg, metrics, ctx, dst);
|
super(cfg, metrics, tsc, ctx, dst);
|
||||||
libdir = site.lib_dir;
|
libdir = site.lib_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.pgm.util;
|
package com.google.gerrit.pgm.util;
|
||||||
|
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
|
import com.google.gerrit.server.config.ThreadSettingsConfig;
|
||||||
import com.google.gerrit.server.schema.DataSourceProvider;
|
import com.google.gerrit.server.schema.DataSourceProvider;
|
||||||
import com.google.gerrit.server.schema.DataSourceType;
|
import com.google.gerrit.server.schema.DataSourceType;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
@@ -34,14 +35,15 @@ public class ThreadLimiter {
|
|||||||
return limitThreads(
|
return limitThreads(
|
||||||
dbInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)),
|
dbInjector.getInstance(Key.get(Config.class, GerritServerConfig.class)),
|
||||||
dbInjector.getInstance(DataSourceType.class),
|
dbInjector.getInstance(DataSourceType.class),
|
||||||
|
dbInjector.getInstance(ThreadSettingsConfig.class),
|
||||||
threads);
|
threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int limitThreads(Config cfg, DataSourceType dst, int threads) {
|
private static int limitThreads(Config cfg, DataSourceType dst,
|
||||||
|
ThreadSettingsConfig threadSettingsConfig, int threads) {
|
||||||
boolean usePool = cfg.getBoolean("database", "connectionpool",
|
boolean usePool = cfg.getBoolean("database", "connectionpool",
|
||||||
dst.usePool());
|
dst.usePool());
|
||||||
int poolLimit = cfg.getInt("database", "poollimit",
|
int poolLimit = threadSettingsConfig.getDatabasePoolLimit();
|
||||||
DataSourceProvider.DEFAULT_POOL_LIMIT);
|
|
||||||
if (usePool && threads > poolLimit) {
|
if (usePool && threads > poolLimit) {
|
||||||
log.warn("Limiting program to " + poolLimit
|
log.warn("Limiting program to " + poolLimit
|
||||||
+ " threads due to database.poolLimit");
|
+ " threads due to database.poolLimit");
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (C) 2015 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.google.gerrit.server.config;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ThreadSettingsConfig {
|
||||||
|
private final int sshdThreads;
|
||||||
|
private final int httpdMaxThreads;
|
||||||
|
private final int sshdBatchThreads;
|
||||||
|
private final int databasePoolLimit;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ThreadSettingsConfig(@GerritServerConfig Config cfg) {
|
||||||
|
int cores = Runtime.getRuntime().availableProcessors();
|
||||||
|
sshdThreads = cfg.getInt("sshd", "threads", 3 * cores / 2);
|
||||||
|
httpdMaxThreads = cfg.getInt("httpd", "maxThreads", 25);
|
||||||
|
int defaultDatabasePoolLimit = sshdThreads + httpdMaxThreads + 2;
|
||||||
|
databasePoolLimit =
|
||||||
|
cfg.getInt("database", "poolLimit", defaultDatabasePoolLimit);
|
||||||
|
sshdBatchThreads = cores == 1 ? 1 : 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabasePoolLimit() {
|
||||||
|
return databasePoolLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHttpdMaxThreads() {
|
||||||
|
return httpdMaxThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSshdThreads() {
|
||||||
|
return sshdThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSshdBatchTreads() {
|
||||||
|
return sshdBatchThreads;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ import com.google.gerrit.metrics.MetricMaker;
|
|||||||
import com.google.gerrit.server.config.ConfigSection;
|
import com.google.gerrit.server.config.ConfigSection;
|
||||||
import com.google.gerrit.server.config.ConfigUtil;
|
import com.google.gerrit.server.config.ConfigUtil;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
|
import com.google.gerrit.server.config.ThreadSettingsConfig;
|
||||||
import com.google.gwtorm.jdbc.SimpleDataSource;
|
import com.google.gwtorm.jdbc.SimpleDataSource;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -47,21 +48,22 @@ import javax.sql.DataSource;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class DataSourceProvider implements Provider<DataSource>,
|
public class DataSourceProvider implements Provider<DataSource>,
|
||||||
LifecycleListener {
|
LifecycleListener {
|
||||||
public static final int DEFAULT_POOL_LIMIT = 8;
|
|
||||||
|
|
||||||
private final Config cfg;
|
private final Config cfg;
|
||||||
private final MetricMaker metrics;
|
private final MetricMaker metrics;
|
||||||
private final Context ctx;
|
private final Context ctx;
|
||||||
private final DataSourceType dst;
|
private final DataSourceType dst;
|
||||||
|
private final ThreadSettingsConfig threadSettingsConfig;
|
||||||
private DataSource ds;
|
private DataSource ds;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected DataSourceProvider(@GerritServerConfig Config cfg,
|
protected DataSourceProvider(@GerritServerConfig Config cfg,
|
||||||
MetricMaker metrics,
|
MetricMaker metrics,
|
||||||
|
ThreadSettingsConfig threadSettingsConfig,
|
||||||
Context ctx,
|
Context ctx,
|
||||||
DataSourceType dst) {
|
DataSourceType dst) {
|
||||||
this.cfg = cfg;
|
this.cfg = cfg;
|
||||||
this.metrics = metrics;
|
this.metrics = metrics;
|
||||||
|
this.threadSettingsConfig = threadSettingsConfig;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.dst = dst;
|
this.dst = dst;
|
||||||
}
|
}
|
||||||
@@ -127,7 +129,7 @@ public class DataSourceProvider implements Provider<DataSource>,
|
|||||||
if (password != null && !password.isEmpty()) {
|
if (password != null && !password.isEmpty()) {
|
||||||
ds.setPassword(password);
|
ds.setPassword(password);
|
||||||
}
|
}
|
||||||
ds.setMaxActive(cfg.getInt("database", "poollimit", DEFAULT_POOL_LIMIT));
|
ds.setMaxActive(threadSettingsConfig.getDatabasePoolLimit());
|
||||||
ds.setMinIdle(cfg.getInt("database", "poolminidle", 4));
|
ds.setMinIdle(cfg.getInt("database", "poolminidle", 4));
|
||||||
ds.setMaxIdle(cfg.getInt("database", "poolmaxidle", 4));
|
ds.setMaxIdle(cfg.getInt("database", "poolmaxidle", 4));
|
||||||
ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null,
|
ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.sshd;
|
package com.google.gerrit.sshd;
|
||||||
|
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
|
import com.google.gerrit.server.config.ThreadSettingsConfig;
|
||||||
import com.google.gerrit.server.git.QueueProvider;
|
import com.google.gerrit.server.git.QueueProvider;
|
||||||
import com.google.gerrit.server.git.WorkQueue;
|
import com.google.gerrit.server.git.WorkQueue;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@@ -31,11 +32,13 @@ public class CommandExecutorQueueProvider implements QueueProvider {
|
|||||||
private final WorkQueue.Executor batchExecutor;
|
private final WorkQueue.Executor batchExecutor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommandExecutorQueueProvider(@GerritServerConfig final Config config,
|
public CommandExecutorQueueProvider(
|
||||||
final WorkQueue queues) {
|
@GerritServerConfig Config config,
|
||||||
final int cores = Runtime.getRuntime().availableProcessors();
|
ThreadSettingsConfig threadsSettingsConfig,
|
||||||
poolSize = config.getInt("sshd", "threads", 3 * cores / 2);
|
WorkQueue queues) {
|
||||||
batchThreads = config.getInt("sshd", "batchThreads", cores == 1 ? 1 : 2);
|
poolSize = threadsSettingsConfig.getSshdThreads();
|
||||||
|
batchThreads = config.getInt("sshd", "batchThreads",
|
||||||
|
threadsSettingsConfig.getSshdBatchTreads());
|
||||||
if (batchThreads > poolSize) {
|
if (batchThreads > poolSize) {
|
||||||
poolSize += batchThreads;
|
poolSize += batchThreads;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user