Commit 449aa8cc authored by 李健华's avatar 李健华

Merge branch 'hotfix/datasource-max-pool-size-20220913' into 'master'

设置datasource pool size

See merge request !92
parents 752419fa 59578b77
package cn.quantgroup.tech.db;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private static final Logger log = LoggerFactory.getLogger(cn.quantgroup.tech.db.DynamicDataSourceRegister.class);
private ConversionService conversionService = new DefaultConversionService();
private static final String DATASOURCE_TYPE_DEFAULT = "com.zaxxer.hikari.HikariDataSource";
private static final String DATABASE_TYPE_DEFAULT = "com.mysql.jdbc.Driver";
private static final String MASTER_PREFIX = "spring.datasource.";
private static final String SLAVE_PREFIX = "slave.datasource.";
private DataSource masterDataSource;
private DataSource slaveDataSource;
public DynamicDataSourceRegister() {
}
public void setEnvironment(Environment environment) {
this.masterDataSource = this.buildDataSource(this.initDataSource(environment, "spring.datasource."));
this.dataBinder(this.masterDataSource, environment, "spring.datasource.");
this.slaveDataSource = this.buildDataSource(this.initDataSource(environment, "slave.datasource."));
this.dataBinder(this.slaveDataSource, environment, "slave.datasource.");
}
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
Map<Object, Object> targetDataSources = new HashMap(1);
targetDataSources.put(DSType.MASTER, this.masterDataSource);
DynamicDataSourceContextHolder.dataSourceIds.add(DSType.MASTER);
targetDataSources.put(DSType.SLAVE, this.slaveDataSource);
DynamicDataSourceContextHolder.dataSourceIds.add(DSType.SLAVE);
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DynamicDataSource.class);
beanDefinition.setSynthetic(true);
MutablePropertyValues mpv = beanDefinition.getPropertyValues();
mpv.addPropertyValue("defaultTargetDataSource", this.masterDataSource);
mpv.addPropertyValue("targetDataSources", targetDataSources);
beanDefinitionRegistry.registerBeanDefinition("dataSource", beanDefinition);
log.info("Dynamic DataSource Registry Success");
}
private Map<String, Object> initDataSource(Environment env, String prefix) {
RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, prefix);
Map<String, Object> dsMap = new HashMap(1);
dsMap.put("type", propertyResolver.getProperty("type", "com.zaxxer.hikari.HikariDataSource"));
dsMap.put("driver-class-name", propertyResolver.getProperty("driver-class-name", "com.mysql.jdbc.Driver"));
dsMap.put("url", propertyResolver.getProperty("url"));
dsMap.put("username", propertyResolver.getProperty("username"));
dsMap.put("password", propertyResolver.getProperty("password"));
dsMap.put("maxPoolSize", propertyResolver.getProperty("maxPoolSize"));
return dsMap;
}
private void dataBinder(DataSource dataSource, Environment env, String prefix) {
RelaxedDataBinder dataBinder = new RelaxedDataBinder(dataSource);
dataBinder.setConversionService(this.conversionService);
dataBinder.setIgnoreNestedProperties(false);
dataBinder.setIgnoreInvalidFields(false);
dataBinder.setIgnoreUnknownFields(true);
Map<String, Object> rpr = (new RelaxedPropertyResolver(env, prefix)).getSubProperties("");
Map<String, Object> values = new HashMap(rpr);
values.remove("type");
values.remove("driver-class-name");
values.remove("url");
values.remove("username");
values.remove("password");
PropertyValues dataSourcePropertyValues = new MutablePropertyValues(values);
dataBinder.bind(dataSourcePropertyValues);
}
private DataSource buildDataSource(Map<String, Object> dsMap) {
try {
String type = dsMap.get("type").toString();
Class<? extends DataSource> dataSourceType = (Class<? extends DataSource>)Class.forName(type);
String driverClassName = dsMap.get("driver-class-name").toString();
String url = dsMap.get("url").toString();
String username = dsMap.get("username").toString();
String password = dsMap.get("password").toString();
Integer maxPoolSize = Integer.parseInt(dsMap.get("maxPoolSize").toString());
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setPassword(password);
config.setUsername(username);
// 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
//线上是双核机器,100已经非常多。。。。
config.setMaximumPoolSize(maxPoolSize);
config.setMinimumIdle(20);
//个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
config.setIdleTimeout(60000);
//等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
config.setConnectionTimeout(30000);
config.setValidationTimeout(3000);
//个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,
// 参考MySQL wait_timeout参数(show variables like '%timeout%';)
config.setMaxLifetime(TimeUnit.HOURS.toMillis(7));
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
HikariDataSource datasource = new HikariDataSource(config);
// DataSourceBuilder factory = DataSourceBuilder.create().driverClassName(driverClassName).url(url).username(username).password(password).type(dataSourceType);
return datasource;
} catch (ClassNotFoundException var9) {
log.error("找不到数据源..你没配置hikari的包么? :{}", var9.getMessage());
return null;
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment