diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolProperties.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolProperties.java new file mode 100644 index 000000000..0a6ca12a7 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolProperties.java @@ -0,0 +1,84 @@ +/* + * Copyright 1999-2020 Alibaba Group Holding Ltd. + * + * 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.alibaba.nacos.config.server.service.datasource; + +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.core.env.Environment; + +import java.util.concurrent.TimeUnit; + +/** + * DataSource pool properties. + * + *

Nacos server use HikariCP as the datasource pool. So the basic pool properties will based on {@link + * com.zaxxer.hikari.HikariDataSource}. + * + * @author xiweng.yy + */ +public class DataSourcePoolProperties { + + public static final long DEFAULT_CONNECTION_TIMEOUT = TimeUnit.SECONDS.toMillis(30L); + + public static final long DEFAULT_VALIDATION_TIMEOUT = TimeUnit.SECONDS.toMillis(10L); + + public static final int DEFAULT_MAX_POOL_SIZE = 20; + + public static final int DEFAULT_MINIMUM_IDLE = 2; + + private final HikariDataSource dataSource; + + private DataSourcePoolProperties() { + dataSource = new HikariDataSource(); + dataSource.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT); + dataSource.setValidationTimeout(DEFAULT_VALIDATION_TIMEOUT); + dataSource.setMaximumPoolSize(DEFAULT_MAX_POOL_SIZE); + dataSource.setMinimumIdle(DEFAULT_MINIMUM_IDLE); + } + + /** + * Build new Hikari config. + * + * @return new hikari config + */ + public static DataSourcePoolProperties build(Environment environment) { + DataSourcePoolProperties result = new DataSourcePoolProperties(); + Binder.get(environment).bind("db.pool.config", Bindable.ofInstance(result.getDataSource())); + return result; + } + + public void setDriverClassName(final String driverClassName) { + dataSource.setDriverClassName(driverClassName); + } + + public void setJdbcUrl(final String jdbcUrl) { + dataSource.setJdbcUrl(jdbcUrl); + } + + public void setUsername(final String username) { + dataSource.setUsername(username); + } + + public void setPassword(final String password) { + dataSource.setPassword(password); + } + + public HikariDataSource getDataSource() { + return dataSource; + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java index 8f55d169f..80023ce02 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java @@ -13,20 +13,18 @@ package com.alibaba.nacos.config.server.service.datasource; -import static com.alibaba.nacos.common.utils.CollectionUtils.getOrDefault; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - +import com.google.common.base.Preconditions; +import com.zaxxer.hikari.HikariDataSource; import org.apache.commons.collections.CollectionUtils; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.env.Environment; -import com.google.common.base.Preconditions; -import com.zaxxer.hikari.HikariDataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static com.alibaba.nacos.common.utils.CollectionUtils.getOrDefault; /** * Properties of external DataSource. @@ -37,15 +35,7 @@ public class ExternalDataSourceProperties { private static final String JDBC_DRIVER_NAME = "com.mysql.cj.jdbc.Driver"; - public static final long CONNECTION_TIMEOUT_MS = 3000L; - - public static final long VALIDATION_TIMEOUT = 10L; - - public static final String TEST_QUERY = "SELECT 1 FROM dual"; - - public static final int DEFAULT_MAX_POOL_SIZE = 20; - - public static final int DEFAULT_MINIMUM_IDLE = 20; + private static final String TEST_QUERY = "SELECT 1"; private Integer num; @@ -55,10 +45,6 @@ public class ExternalDataSourceProperties { private List password = new ArrayList<>(); - private List maxPoolSize = new ArrayList<>(); - - private List minIdle = new ArrayList<>(); - public void setNum(Integer num) { this.num = num; } @@ -75,14 +61,6 @@ public class ExternalDataSourceProperties { this.password = password; } - public void setMaxPoolSize(List maxPoolSize) { - this.maxPoolSize = maxPoolSize; - } - - public void setMinIdle(List minIdle) { - this.minIdle = minIdle; - } - /** * Build serveral HikariDataSource. * @@ -99,16 +77,12 @@ public class ExternalDataSourceProperties { for (int index = 0; index < num; index++) { int currentSize = index + 1; Preconditions.checkArgument(url.size() >= currentSize, "db.url.%s is null", index); - HikariDataSource ds = new HikariDataSource(); - ds.setDriverClassName(JDBC_DRIVER_NAME); - ds.setJdbcUrl(url.get(index).trim()); - ds.setUsername(getOrDefault(user, index, user.get(0)).trim()); - ds.setPassword(getOrDefault(password, index, password.get(0)).trim()); - ds.setConnectionTimeout(CONNECTION_TIMEOUT_MS); - ds.setMaximumPoolSize(getOrDefault(maxPoolSize, index, DEFAULT_MAX_POOL_SIZE)); - ds.setMinimumIdle(getOrDefault(minIdle, index, DEFAULT_MINIMUM_IDLE)); - // Check the connection pool every 10 minutes - ds.setValidationTimeout(TimeUnit.MINUTES.toMillis(VALIDATION_TIMEOUT)); + DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment); + poolProperties.setDriverClassName(JDBC_DRIVER_NAME); + poolProperties.setJdbcUrl(url.get(index).trim()); + poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim()); + poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim()); + HikariDataSource ds = poolProperties.getDataSource(); ds.setConnectionTestQuery(TEST_QUERY); dataSources.add(ds); callback.accept(ds); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java index 7bd3ad753..99688fed2 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java @@ -16,33 +16,29 @@ package com.alibaba.nacos.config.server.service.datasource; -import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.CONFIG_INFO4BETA_ROW_MAPPER; -import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; -import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.sql.DataSource; - -import com.alibaba.nacos.common.utils.IPUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.CannotGetJdbcConnectionException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.support.TransactionTemplate; - import com.alibaba.nacos.common.utils.ConvertUtils; +import com.alibaba.nacos.common.utils.IPUtil; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.monitor.MetricsMonitor; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.sys.utils.ApplicationUtils; import com.zaxxer.hikari.HikariDataSource; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.CONFIG_INFO4BETA_ROW_MAPPER; +import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; +import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG; /** * Base data source. @@ -51,10 +47,6 @@ import com.zaxxer.hikari.HikariDataSource; */ public class ExternalDataSourceServiceImpl implements DataSourceService { - private static final Logger LOGGER = LoggerFactory.getLogger(ExternalDataSourceServiceImpl.class); - - private static final String JDBC_DRIVER_NAME = "com.mysql.cj.jdbc.Driver"; - /** * JDBC execute timeout value, unit:second. */ @@ -198,10 +190,6 @@ public class ExternalDataSourceServiceImpl implements DataSourceService { return "UP"; } - static String defaultIfNull(String value, String defaultValue) { - return null == value ? defaultValue : value; - } - class SelectMasterTask implements Runnable { @Override diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/LocalDataSourceServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/LocalDataSourceServiceImpl.java index 3fb412e4d..33224ee78 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/LocalDataSourceServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/LocalDataSourceServiceImpl.java @@ -24,7 +24,13 @@ import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.sys.utils.ApplicationUtils; import com.alibaba.nacos.sys.utils.DiskUtils; import com.zaxxer.hikari.HikariDataSource; +import org.apache.commons.lang3.StringUtils; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; +import javax.annotation.PostConstruct; +import javax.sql.DataSource; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; @@ -36,13 +42,6 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; -import javax.annotation.PostConstruct; -import javax.sql.DataSource; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.support.TransactionTemplate; /** * local data source. @@ -121,7 +120,7 @@ public class LocalDataSourceServiceImpl implements DataSourceService { /** * Restore derby. * - * @param jdbcUrl jdbcUrl string value. + * @param jdbcUrl jdbcUrl string value. * @param callable callable. * @throws Exception exception. */ @@ -145,14 +144,12 @@ public class LocalDataSourceServiceImpl implements DataSourceService { } private synchronized void initialize(String jdbcUrl) { - HikariDataSource ds = new HikariDataSource(); - ds.setDriverClassName(jdbcDriverName); - ds.setJdbcUrl(jdbcUrl); - ds.setUsername(userName); - ds.setPassword(password); - ds.setIdleTimeout(30_000L); - ds.setMaximumPoolSize(80); - ds.setConnectionTimeout(10000L); + DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(ApplicationUtils.getEnvironment()); + poolProperties.setDriverClassName(jdbcDriverName); + poolProperties.setJdbcUrl(jdbcUrl); + poolProperties.setUsername(userName); + poolProperties.setPassword(password); + HikariDataSource ds = poolProperties.getDataSource(); DataSourceTransactionManager tm = new DataSourceTransactionManager(); tm.setDataSource(ds); if (jdbcTemplateInit) { diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolPropertiesTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolPropertiesTest.java new file mode 100644 index 000000000..fbc9dcf10 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/DataSourcePoolPropertiesTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 1999-2020 Alibaba Group Holding Ltd. + * + * 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.alibaba.nacos.config.server.service.datasource; + +import com.zaxxer.hikari.HikariDataSource; +import org.junit.Before; +import org.junit.Test; +import org.springframework.mock.env.MockEnvironment; + +import static org.junit.Assert.assertEquals; + +public class DataSourcePoolPropertiesTest { + + private static final String JDBC_URL = "jdbc:derby://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&serverTimezone=UTC"; + + private static final String JDBC_DRIVER_CLASS_NAME = "org.apache.derby.jdbc.EmbeddedDriver"; + + private static final String PASSWORD = "nacos"; + + private static final String USERNAME = "nacos_devtest"; + + private static final Long CONNECTION_TIMEOUT = 10000L; + + private static final Integer MAX_POOL_SIZE = 50; + + private MockEnvironment environment; + + @Before + public void setUp() throws Exception { + environment = new MockEnvironment(); + environment.setProperty("db.user", USERNAME); + environment.setProperty("db.password", PASSWORD); + environment.setProperty("db.pool.config.connectionTimeout", CONNECTION_TIMEOUT.toString()); + environment.setProperty("db.pool.config.maximumPoolSize", MAX_POOL_SIZE.toString()); + } + + @Test + public void testBuild() { + DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment); + poolProperties.setJdbcUrl(JDBC_URL); + poolProperties.setDriverClassName(JDBC_DRIVER_CLASS_NAME); + poolProperties.setUsername(USERNAME); + poolProperties.setPassword(PASSWORD); + HikariDataSource actual = poolProperties.getDataSource(); + assertEquals(JDBC_URL, actual.getJdbcUrl()); + assertEquals(JDBC_DRIVER_CLASS_NAME, actual.getDriverClassName()); + assertEquals(USERNAME, actual.getUsername()); + assertEquals(PASSWORD, actual.getPassword()); + assertEquals(CONNECTION_TIMEOUT.longValue(), actual.getConnectionTimeout()); + assertEquals(DataSourcePoolProperties.DEFAULT_VALIDATION_TIMEOUT, actual.getValidationTimeout()); + assertEquals(MAX_POOL_SIZE.intValue(), actual.getMaximumPoolSize()); + assertEquals(DataSourcePoolProperties.DEFAULT_MINIMUM_IDLE, actual.getMinimumIdle()); + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java index e7ad61363..2b6ef39d1 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java @@ -107,7 +107,7 @@ public class ExternalDataSourcePropertiesTest { environment.setProperty("db.url.0", JDBC_URL); List dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> { dataSource.validate(); - Assert.assertEquals(dataSource.getMinimumIdle(), ExternalDataSourceProperties.DEFAULT_MINIMUM_IDLE); + Assert.assertEquals(dataSource.getMinimumIdle(), DataSourcePoolProperties.DEFAULT_MINIMUM_IDLE); })); Assert.assertEquals(dataSources.size(), 1); } diff --git a/config/src/test/resources/jdbc.properties b/config/src/test/resources/jdbc.properties deleted file mode 100755 index 49021f5d0..000000000 --- a/config/src/test/resources/jdbc.properties +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright 1999-2018 Alibaba Group Holding Ltd. -# -# 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. -# - diff --git a/distribution/conf/application.properties b/distribution/conf/application.properties index bce0d38c8..4f4fd8804 100644 --- a/distribution/conf/application.properties +++ b/distribution/conf/application.properties @@ -40,6 +40,11 @@ server.port=8848 # db.user=nacos # db.password=nacos +### Connection pool configuration: hikariCP +db.pool.config.connectionTimeout=30000 +db.pool.config.validationTimeout=10000 +db.pool.config.maximumPoolSize=20 +db.pool.config.minimumIdle=2 #*************** Naming Module Related Configurations ***************# ### Data dispatch task execution period in milliseconds: