framework/db: use HikariCP as default and improvements (#9518)

Per docs, if the mysql connector is JDBC2 compliant then it should use
the Connection.isValid API to test a connection.
(https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#isValid-int-)

This would significantly reduce query lags and API throughput, as for
every SQL query one or two SELECT 1 are performed everytime a Connection
is given to application logic.

This should only be accepted when the driver is JDBC4 complaint.

As per the docs, the connector-j can use /* ping */ before calling
SELECT 1 to have light weight application pings to the server:
https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html

Replaces dbcp2 connection pool library with more performant HikariCP.
With this unit tests are failing but build is passing.

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Co-authored-by: Rohit Yadav <rohityadav89@gmail.com>
This commit is contained in:
Abhishek Kumar 2024-09-05 09:36:58 +05:30 committed by GitHub
parent 31b0ed0a18
commit 7e085d5e1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 229 additions and 43 deletions

View File

@ -34,10 +34,14 @@ db.cloud.uri=
# CloudStack database tuning parameters
db.cloud.connectionPoolLib=hikaricp
db.cloud.maxActive=250
db.cloud.maxIdle=30
db.cloud.maxWait=10000
db.cloud.validationQuery=SELECT 1
db.cloud.maxWait=600000
db.cloud.minIdleConnections=5
db.cloud.connectionTimeout=30000
db.cloud.keepAliveTime=600000
db.cloud.validationQuery=/* ping */ SELECT 1
db.cloud.testOnBorrow=true
db.cloud.testWhileIdle=true
db.cloud.timeBetweenEvictionRunsMillis=40000
@ -70,9 +74,13 @@ db.usage.uri=
# usage database tuning parameters
db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100
db.usage.maxIdle=30
db.usage.maxWait=10000
db.usage.maxWait=600000
db.usage.minIdleConnections=5
db.usage.connectionTimeout=30000
db.usage.keepAliveTime=600000
db.usage.url.params=serverTimezone=UTC
# Simulator database settings
@ -82,9 +90,13 @@ db.simulator.host=@DBHOST@
db.simulator.driver=@DBDRIVER@
db.simulator.port=3306
db.simulator.name=simulator
db.simulator.connectionPoolLib=hikaricp
db.simulator.maxActive=250
db.simulator.maxIdle=30
db.simulator.maxWait=10000
db.simulator.maxWait=600000
db.simulator.minIdleConnections=5
db.simulator.connectionTimeout=30000
db.simulator.keepAliveTime=600000
db.simulator.autoReconnect=true
# Connection URI to the database "simulator". When this property is set, only the following properties will be used along with it: db.simulator.host, db.simulator.port, db.simulator.name, db.simulator.autoReconnect. Other properties will be ignored.

View File

@ -42,6 +42,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>

View File

@ -116,10 +116,6 @@ public class DatabaseCreator {
}
public static void main(String[] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"/com/cloud/upgrade/databaseCreatorContext.xml"});
appContext.getBean(ComponentContext.class);
String dbPropsFile = "";
List<String> sqlFiles = new ArrayList<String>();
List<String> upgradeClasses = new ArrayList<String>();
@ -166,13 +162,17 @@ public class DatabaseCreator {
System.exit(1);
}
initDB(dbPropsFile, rootPassword, databases, dryRun);
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"/com/cloud/upgrade/databaseCreatorContext.xml"});
appContext.getBean(ComponentContext.class);
try {
TransactionLegacy.initDataSource(dbPropsFile);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
initDB(dbPropsFile, rootPassword, databases, dryRun);
// Process sql files
for (String sqlFile : sqlFiles) {

View File

@ -56,6 +56,11 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -40,6 +40,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
@ -48,6 +52,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>

View File

@ -145,7 +145,7 @@ public class ConnectionConcierge {
protected String testValidity(String name, Connection conn) {
if (conn != null) {
synchronized (conn) {
try (PreparedStatement pstmt = conn.prepareStatement("SELECT 1");) {
try (PreparedStatement pstmt = conn.prepareStatement("/* ping */ SELECT 1");) {
pstmt.executeQuery();
} catch (Throwable th) {
logger.error("Unable to keep the db connection for " + name, th);

View File

@ -38,17 +38,20 @@ import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cloud.utils.Pair;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.mgmt.JmxUtil;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
/**
* Transaction abstracts away the Connection object in JDBC. It allows the
@ -95,6 +98,8 @@ public class TransactionLegacy implements Closeable {
}
}
private static final String CONNECTION_POOL_LIB_DBCP = "dbcp";
private final LinkedList<StackElement> _stack;
private long _id;
@ -1020,6 +1025,21 @@ public class TransactionLegacy implements Closeable {
}
}
private static <T extends Number> T parseNumber(String value, Class<T> type) {
if (value == null) {
return null;
}
try {
if (type.equals(Long.class)) {
return type.cast(Long.parseLong(value));
} else {
return type.cast(Integer.parseInt(value));
}
} catch (NumberFormatException ignored) {
return null;
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void initDataSource(Properties dbProps) {
try {
@ -1030,9 +1050,12 @@ public class TransactionLegacy implements Closeable {
LOGGER.info("Is Data Base High Availiability enabled? Ans : " + s_dbHAEnabled);
String loadBalanceStrategy = dbProps.getProperty("db.ha.loadBalanceStrategy");
// FIXME: If params are missing...default them????
final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
final Integer cloudMaxActive = parseNumber(dbProps.getProperty("db.cloud.maxActive"), Integer.class);
final Integer cloudMaxIdle = parseNumber(dbProps.getProperty("db.cloud.maxIdle"), Integer.class);
final Long cloudMaxWait = parseNumber(dbProps.getProperty("db.cloud.maxWait"), Long.class);
final Integer cloudMinIdleConnections = parseNumber(dbProps.getProperty("db.cloud.minIdleConnections"), Integer.class);
final Long cloudConnectionTimeout = parseNumber(dbProps.getProperty("db.cloud.connectionTimeout"), Long.class);
final Long cloudKeepAliveTimeout = parseNumber(dbProps.getProperty("db.cloud.keepAliveTime"), Long.class);
final String cloudUsername = dbProps.getProperty("db.cloud.username");
final String cloudPassword = dbProps.getProperty("db.cloud.password");
final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery");
@ -1071,14 +1094,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(cloudUriAndDriver.second());
// Default Data Source for CloudStack
s_ds = createDataSource(cloudUriAndDriver.first(), cloudUsername, cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
cloudTimeBtwEvictionRunsMillis, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle, cloudTestOnBorrow,
cloudValidationQuery, isolationLevel);
s_ds = createDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), cloudUriAndDriver.first(),
cloudUsername, cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
cloudTimeBtwEvictionRunsMillis, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle,
cloudTestOnBorrow, cloudValidationQuery, cloudMinIdleConnections, cloudConnectionTimeout,
cloudKeepAliveTimeout, isolationLevel, "cloud");
// Configure the usage db
final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
final Integer usageMaxActive = parseNumber(dbProps.getProperty("db.usage.maxActive"), Integer.class);
final Integer usageMaxIdle = parseNumber(dbProps.getProperty("db.usage.maxIdle"), Integer.class);
final Long usageMaxWait = parseNumber(dbProps.getProperty("db.usage.maxWait"), Long.class);
final Integer usageMinIdleConnections = parseNumber(dbProps.getProperty("db.usage.minIdleConnections"), Integer.class);
final Long usageConnectionTimeout = parseNumber(dbProps.getProperty("db.usage.connectionTimeout"), Long.class);
final Long usageKeepAliveTimeout = parseNumber(dbProps.getProperty("db.usage.keepAliveTime"), Long.class);
final String usageUsername = dbProps.getProperty("db.usage.username");
final String usagePassword = dbProps.getProperty("db.usage.password");
@ -1087,15 +1115,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(usageUriAndDriver.second());
// Data Source for usage server
s_usageDS = createDataSource(usageUriAndDriver.first(), usageUsername, usagePassword,
usageMaxActive, usageMaxIdle, usageMaxWait, null, null, null, null,
null, isolationLevel);
s_usageDS = createDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), usageUriAndDriver.first(),
usageUsername, usagePassword, usageMaxActive, usageMaxIdle, usageMaxWait, null,
null, null, null, null,
usageMinIdleConnections, usageConnectionTimeout, usageKeepAliveTimeout, isolationLevel, "usage");
try {
// Configure the simulator db
final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
final Integer simulatorMaxActive = parseNumber(dbProps.getProperty("db.simulator.maxActive"), Integer.class);
final Integer simulatorMaxIdle = parseNumber(dbProps.getProperty("db.simulator.maxIdle"), Integer.class);
final Long simulatorMaxWait = parseNumber(dbProps.getProperty("db.simulator.maxWait"), Long.class);
final Integer simulatorMinIdleConnections = parseNumber(dbProps.getProperty("db.simulator.minIdleConnections"), Integer.class);
final Long simulatorConnectionTimeout = parseNumber(dbProps.getProperty("db.simulator.connectionTimeout"), Long.class);
final Long simulatorKeepAliveTimeout = parseNumber(dbProps.getProperty("db.simulator.keepAliveTime"), Long.class);
final String simulatorUsername = dbProps.getProperty("db.simulator.username");
final String simulatorPassword = dbProps.getProperty("db.simulator.password");
@ -1122,15 +1154,18 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(simulatorDriver);
s_simulatorDS = createDataSource(simulatorConnectionUri, simulatorUsername, simulatorPassword,
simulatorMaxActive, simulatorMaxIdle, simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel);
s_simulatorDS = createDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"),
simulatorConnectionUri, simulatorUsername, simulatorPassword, simulatorMaxActive,
simulatorMaxIdle, simulatorMaxWait, null, null, null, null,
cloudValidationQuery, simulatorMinIdleConnections, simulatorConnectionTimeout,
simulatorKeepAliveTimeout, isolationLevel, "simulator");
} catch (Exception e) {
LOGGER.debug("Simulator DB properties are not available. Not initializing simulator DS");
}
} catch (final Exception e) {
s_ds = getDefaultDataSource("cloud");
s_usageDS = getDefaultDataSource("cloud_usage");
s_simulatorDS = getDefaultDataSource("cloud_simulator");
s_ds = getDefaultDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), "cloud");
s_usageDS = getDefaultDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), "cloud_usage");
s_simulatorDS = getDefaultDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"), "simulator");
LOGGER.warn(
"Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration",
e);
@ -1222,11 +1257,71 @@ public class TransactionLegacy implements Closeable {
/**
* Creates a data source
*/
private static DataSource createDataSource(String uri, String username, String password,
private static DataSource createDataSource(String connectionPoolLib, String uri, String username, String password,
Integer maxActive, Integer maxIdle, Long maxWait, Long timeBtwnEvictionRuns, Long minEvictableIdleTime,
Boolean testWhileIdle, Boolean testOnBorrow, String validationQuery, Integer minIdleConnections,
Long connectionTimeout, Long keepAliveTime, Integer isolationLevel, String dsName) {
LOGGER.debug("Creating datasource for database: {} with connection pool lib: {}", dsName,
connectionPoolLib);
if (CONNECTION_POOL_LIB_DBCP.equals(connectionPoolLib)) {
return createDbcpDataSource(uri, username, password, maxActive, maxIdle, maxWait, timeBtwnEvictionRuns,
minEvictableIdleTime, testWhileIdle, testOnBorrow, validationQuery, isolationLevel);
}
return createHikaricpDataSource(uri, username, password, maxActive, maxIdle, maxWait, minIdleConnections,
connectionTimeout, keepAliveTime, isolationLevel, dsName);
}
private static DataSource createHikaricpDataSource(String uri, String username, String password,
Integer maxActive, Integer maxIdle, Long maxWait,
Long timeBtwnEvictionRuns, Long minEvictableIdleTime,
Boolean testWhileIdle, Boolean testOnBorrow,
String validationQuery, Integer isolationLevel) {
Integer minIdleConnections, Long connectionTimeout, Long keepAliveTime,
Integer isolationLevel, String dsName) {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(uri);
config.setUsername(username);
config.setPassword(password);
config.setPoolName(dsName);
// Connection pool properties
config.setMaximumPoolSize(ObjectUtils.defaultIfNull(maxActive, 250));
config.setIdleTimeout(ObjectUtils.defaultIfNull(maxIdle, 30) * 1000);
config.setMaxLifetime(ObjectUtils.defaultIfNull(maxWait, 600000L));
config.setMinimumIdle(ObjectUtils.defaultIfNull(minIdleConnections, 5));
config.setConnectionTimeout(ObjectUtils.defaultIfNull(connectionTimeout, 30000L));
config.setKeepaliveTime(ObjectUtils.defaultIfNull(keepAliveTime, 600000L));
String isolationLevelString = "TRANSACTION_READ_COMMITTED";
if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
isolationLevelString = "TRANSACTION_SERIALIZABLE";
} else if (isolationLevel == Connection.TRANSACTION_READ_UNCOMMITTED) {
isolationLevelString = "TRANSACTION_READ_UNCOMMITTED";
} else if (isolationLevel == Connection.TRANSACTION_REPEATABLE_READ) {
isolationLevelString = "TRANSACTION_REPEATABLE_READ";
}
config.setTransactionIsolation(isolationLevelString);
// Standard datasource config for MySQL
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
// Additional config for MySQL
config.addDataSourceProperty("useServerPrepStmts", "true");
config.addDataSourceProperty("useLocalSessionState", "true");
config.addDataSourceProperty("rewriteBatchedStatements", "true");
config.addDataSourceProperty("cacheResultSetMetadata", "true");
config.addDataSourceProperty("cacheServerConfiguration", "true");
config.addDataSourceProperty("elideSetAutoCommits", "true");
config.addDataSourceProperty("maintainTimeStats", "false");
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
private static DataSource createDbcpDataSource(String uri, String username, String password,
Integer maxActive, Integer maxIdle, Long maxWait,
Long timeBtwnEvictionRuns, Long minEvictableIdleTime,
Boolean testWhileIdle, Boolean testOnBorrow,
String validationQuery, Integer isolationLevel) {
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(uri, username, password);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle, maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle, testOnBorrow);
@ -1267,6 +1362,44 @@ public class TransactionLegacy implements Closeable {
return config;
}
private static DataSource getDefaultDataSource(final String connectionPoolLib, final String database) {
LOGGER.debug("Creating default datasource for database: {} with connection pool lib: {}",
database, connectionPoolLib);
if (CONNECTION_POOL_LIB_DBCP.equalsIgnoreCase(connectionPoolLib)) {
return getDefaultDbcpDataSource(database);
}
return getDefaultHikaricpDataSource(database);
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static DataSource getDefaultHikaricpDataSource(final String database) {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/" + database + "?" + CONNECTION_PARAMS);
config.setUsername("cloud");
config.setPassword("cloud");
config.setPoolName(database);
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
config.setMaximumPoolSize(250);
config.setConnectionTimeout(1000);
config.setIdleTimeout(1000);
config.setKeepaliveTime(1000);
config.setMaxLifetime(1000);
config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
config.setInitializationFailTimeout(-1L);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static DataSource getDefaultDbcpDataSource(final String database) {
final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database + "?" + CONNECTION_PARAMS, "cloud", "cloud");
final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
final GenericObjectPool connectionPool = new GenericObjectPool(poolableConnectionFactory);
return new PoolingDataSource(connectionPool);
}
private static String getDBHAParams(String dbName, Properties dbProps) {
StringBuilder sb = new StringBuilder();
sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName + ".failOverReadOnly"));
@ -1278,14 +1411,6 @@ public class TransactionLegacy implements Closeable {
return sb.toString();
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static DataSource getDefaultDataSource(final String database) {
final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database + "?" + CONNECTION_PARAMS, "cloud", "cloud");
final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
final GenericObjectPool connectionPool = new GenericObjectPool(poolableConnectionFactory);
return new PoolingDataSource(connectionPool);
}
/**
* Used for unit testing primarily
*

View File

@ -32,5 +32,10 @@
<groupId>com.globo.globodns</groupId>
<artifactId>globodns-client</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -47,5 +47,10 @@
<groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

13
pom.xml
View File

@ -102,6 +102,7 @@
<cs.configuration.version>1.10</cs.configuration.version>
<cs.daemon.version>1.3.3</cs.daemon.version>
<cs.dbcp.version>2.9.0</cs.dbcp.version>
<cs.hikaricp.version>5.1.0</cs.hikaricp.version>
<cs.discovery.version>0.5</cs.discovery.version>
<cs.lang.version>2.6</cs.lang.version>
<cs.pool.version>2.9.0</cs.pool.version>
@ -364,6 +365,7 @@
<artifactId>commons-daemon</artifactId>
<version>${cs.daemon.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
@ -375,6 +377,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${cs.hikaricp.version}</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
@ -455,6 +462,12 @@
<artifactId>reload4j</artifactId>
<version>${cs.reload4j.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${cs.mysql.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>

View File

@ -164,6 +164,11 @@
<artifactId>cloud-framework-agent-lb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-configdrive</artifactId>

View File

@ -24,7 +24,11 @@ db.usage.port=3306
db.usage.name=cloud_usage
# usage database tuning parameters
db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100
db.usage.maxIdle=30
db.usage.maxWait=10000
db.usage.minIdleConnections=5
db.usage.connectionTimeout=30000
db.usage.keepAliveTime=600000
db.usage.autoReconnect=true