delete pool

Raod 3 years ago
parent 15c81886ac
commit 01923ae1f4

@ -1,71 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.constant;
/**
* 线
* @since 1.1.0
*/
public final class PooledConst {
private PooledConst(){}
/**
*
* @since 1.1.0
*/
public static final int DEFAULT_MIN_SIZE = 10;
/**
*
* @since 1.1.0
*/
public static final int DEFAULT_MAX_SIZE = 300;
/**
*
*
* 1 min
*
* @since 1.3.0
*/
public static final int DEFAULT_MAX_WAIT_MILLS = 60 * 1000;
/**
*
* @since 1.5.0
*/
public static final String DEFAULT_VALID_QUERY = "select 1 from dual";
/**
*
* @since 1.5.0
*/
public static final int DEFAULT_VALID_TIME_OUT_SECONDS = 5;
/**
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_BORROW = false;
/**
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_RETURN = false;
/**
*
*
* @since 1.5.0
*/
public static final boolean DEFAULT_TEST_ON_IDLE = true;
/**
* 1min
*
* @since 1.5.0
*/
public static final long DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS = 60;
}

@ -1,68 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.datasource;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class AbstractDataSourceConfig extends DataSourceConfigAdaptor {
/**
*
* @since 1.0.0
*/
protected String driverClass;
/**
* jdbc url
* @since 1.0.0
*/
protected String jdbcUrl;
/**
*
* @since 1.0.0
*/
protected String user;
/**
*
* @since 1.0.0
*/
protected String password;
public String getDriverClass() {
return driverClass;
}
@Override
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public String getJdbcUrl() {
return jdbcUrl;
}
@Override
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
public String getUser() {
return user;
}
@Override
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
@Override
public void setPassword(String password) {
this.password = password;
}
}

@ -1,159 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.api.ILifeCycle;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.api.IPooledDataSourceConfig;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.constant.PooledConst;
/**
* @author binbin.hou
* @since 1.1.0
*/
public abstract class AbstractPooledDataSourceConfig extends AbstractDataSourceConfig
implements IPooledDataSourceConfig, ILifeCycle {
/**
*
* @since 1.1.0
*/
protected int minSize = PooledConst.DEFAULT_MIN_SIZE;
/**
*
* @since 1.1.0
*/
protected int maxSize = PooledConst.DEFAULT_MAX_SIZE;
/**
*
* @since 1.3.0
*/
protected long maxWaitMills = PooledConst.DEFAULT_MAX_WAIT_MILLS;
/**
*
* @since 1.5.0
*/
protected String validQuery = PooledConst.DEFAULT_VALID_QUERY;
/**
*
* @since 1.5.0
*/
protected int validTimeOutSeconds = PooledConst.DEFAULT_VALID_TIME_OUT_SECONDS;
/**
*
* @since 1.5.0
*/
protected boolean testOnBorrow = PooledConst.DEFAULT_TEST_ON_BORROW;
/**
*
* @since 1.5.0
*/
protected boolean testOnReturn = PooledConst.DEFAULT_TEST_ON_RETURN;
/**
*
* @since 1.5.0
*/
protected boolean testOnIdle = PooledConst.DEFAULT_TEST_ON_IDLE;
/**
*
* @since 1.5.0
*/
protected long testOnIdleIntervalSeconds = PooledConst.DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS;
public int getMinSize() {
return minSize;
}
@Override
public void setMinSize(int minSize) {
this.minSize = minSize;
}
public int getMaxSize() {
return maxSize;
}
@Override
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
public long getMaxWaitMills() {
return maxWaitMills;
}
@Override
public void setMaxWaitMills(long maxWaitMills) {
this.maxWaitMills = maxWaitMills;
}
public String getValidQuery() {
return validQuery;
}
@Override
public void setValidQuery(String validQuery) {
this.validQuery = validQuery;
}
public int getValidTimeOutSeconds() {
return validTimeOutSeconds;
}
@Override
public void setValidTimeOutSeconds(int validTimeOutSeconds) {
this.validTimeOutSeconds = validTimeOutSeconds;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
@Override
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
@Override
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestOnIdle() {
return testOnIdle;
}
@Override
public void setTestOnIdle(boolean testOnIdle) {
this.testOnIdle = testOnIdle;
}
public long getTestOnIdleIntervalSeconds() {
return testOnIdleIntervalSeconds;
}
@Override
public void setTestOnIdleIntervalSeconds(long testOnIdleIntervalSeconds) {
this.testOnIdleIntervalSeconds = testOnIdleIntervalSeconds;
}
@Override
public void init() {
}
@Override
public void destroy() {
}
}

@ -1,82 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.api.IDataSourceConfig;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class DataSourceConfigAdaptor implements IDataSourceConfig {
@Override
public Connection getConnection() throws SQLException {
return null;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public void setDriverClass(String driverClass) {
}
@Override
public void setJdbcUrl(String jdbcUrl) {
}
@Override
public void setUser(String user) {
}
@Override
public void setPassword(String password) {
}
}

@ -1,240 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.connection.IPooledConnection;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.connection.PooledConnection;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.exception.JdbcPoolException;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.util.DriverClassUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author binbin.hou
* @since 1.1.0
*/
@Slf4j
public class PooledDataSource extends AbstractPooledDataSourceConfig {
/**
*
*
* @since 1.1.0
*/
private List<IPooledConnection> pool = new ArrayList<>();
@Override
public synchronized void init() {
DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
this.initJdbcPool();
// 初始化 idle check
this.initTestOnIdle();
}
@Override
public synchronized Connection getConnection() throws SQLException {
//1. 获取第一个不是 busy 的连接
Optional<IPooledConnection> connectionOptional = getFreeConnectionFromPool();
if (connectionOptional.isPresent()) {
return connectionOptional.get();
}
//2. 考虑是否可以扩容
if (pool.size() >= maxSize) {
//2.1 立刻返回
if (maxWaitMills <= 0) {
throw new JdbcPoolException("Can't get connection from pool!");
}
//2.2 循环等待
final long startWaitMills = System.currentTimeMillis();
final long endWaitMills = startWaitMills + maxWaitMills;
while (System.currentTimeMillis() < endWaitMills) {
Optional<IPooledConnection> optional = getFreeConnectionFromPool();
if (optional.isPresent()) {
return optional.get();
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
log.debug("等待连接池归还wait for 1 mills");
}
//2.3 等待超时
throw new JdbcPoolException("Can't get connection from pool, wait time out for mills: " + maxWaitMills);
}
//3. 扩容(暂时只扩容一个)
log.debug("开始扩容连接池大小step: 1");
IPooledConnection pooledConnection = createPooledConnection();
pooledConnection.setBusy(true);
this.pool.add(pooledConnection);
log.debug("从扩容后的连接池中获取连接");
return pooledConnection;
}
@Override
public void returnConnection(IPooledConnection pooledConnection) {
// 验证状态
if (testOnReturn) {
checkValid(pooledConnection);
}
// 设置为不繁忙
pooledConnection.setBusy(false);
log.debug("归还连接,状态设置为不繁忙");
}
/**
*
*
* @return
* @since 1.3.0
*/
private Optional<IPooledConnection> getFreeConnectionFromPool() {
for (IPooledConnection pc : pool) {
if (!pc.isBusy()) {
pc.setBusy(true);
log.debug("从连接池中获取连接");
// 验证有效性
if (testOnBorrow) {
log.debug("Test on borrow start");
checkValid(pc);
log.debug("Test on borrow finish");
}
return Optional.of(pc);
}
}
// 空
return Optional.empty();
}
/**
* https://stackoverflow.com/questions/3668506/efficient-sql-test-query-or-validation-query-that-will-work-across-all-or-most
* <p>
* 使 {@link Connection#isValid(int)}
*
* @param pooledConnection
* @since 1.5.0
*/
private void checkValid(final IPooledConnection pooledConnection) {
if (StringUtils.isNotEmpty(super.validQuery)) {
Connection connection = pooledConnection.getConnection();
try {
// 如果连接无效,重新申请一个新的替代
if (!connection.isValid(super.validTimeOutSeconds)) {
log.debug("Old connection is inValid, start create one for it.");
Connection newConnection = createConnection();
pooledConnection.setConnection(newConnection);
log.debug("Old connection is inValid, finish create one for it.");
}
} catch (SQLException throwables) {
throw new JdbcPoolException(throwables);
}
} else {
log.debug("valid query is empty, ignore valid.");
}
}
/**
*
*
* @since 1.1.0
*/
private void initJdbcPool() {
final int minSize = super.minSize;
pool = new ArrayList<>(minSize);
for (int i = 0; i < minSize; i++) {
IPooledConnection pooledConnection = createPooledConnection();
pool.add(pooledConnection);
}
}
/**
*
*
* @return
* @since 1.1.0
*/
private IPooledConnection createPooledConnection() {
Connection connection = createConnection();
IPooledConnection pooledConnection = new PooledConnection();
pooledConnection.setBusy(false);
pooledConnection.setConnection(connection);
pooledConnection.setDataSource(this);
return pooledConnection;
}
/**
*
*
* @return
* @since 1.1.0
*/
private Connection createConnection() {
try {
if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
return DriverManager.getConnection(super.getJdbcUrl());
}
return DriverManager.getConnection(super.getJdbcUrl(),
super.getUser(), super.getPassword());
} catch (SQLException e) {
throw new JdbcPoolException(e);
}
}
/**
*
*
* @since 1.5.0
*/
private void initTestOnIdle() {
if (StringUtils.isNotEmpty(validQuery)) {
ScheduledExecutorService idleExecutor = Executors.newSingleThreadScheduledExecutor();
idleExecutor.scheduleAtFixedRate(this::testOnIdleCheck, super.testOnIdleIntervalSeconds, testOnIdleIntervalSeconds, TimeUnit.SECONDS);
log.debug("Test on idle config with interval seonds: " + testOnIdleIntervalSeconds);
}
}
/**
*
*
* @since 1.5.0
*/
private void testOnIdleCheck() {
log.debug("start check test on idle");
for (IPooledConnection pc : this.pool) {
if (!pc.isBusy()) {
checkValid(pc);
}
}
log.debug("finish check test on idle");
}
}

@ -1,26 +0,0 @@
package com.anjiplus.template.gaea.business.modules.dataSource.pool.datasource;
import com.anjiplus.template.gaea.business.modules.dataSource.pool.util.DriverClassUtil;
import org.apache.commons.lang3.StringUtils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class UnPooledDataSource extends AbstractDataSourceConfig {
@Override
public Connection getConnection() throws SQLException {
DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
return DriverManager.getConnection(super.jdbcUrl);
}
return DriverManager.getConnection(super.getJdbcUrl(),
super.getUser(), super.getPassword());
}
}
Loading…
Cancel
Save