1.dispatcher-master.xml
<?xml version="1.0" encoding="utf-8"?>
<config>
<value>{"name":"dispatcher","driverClassName":"com.mysql.jdbc.Driver", "jdbcUrl":"jdbc:mysql://mysql-m-wr-car-all-test-db.01zhuanche.com:3306/dispatcher?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&connectTimeout=1000&socketTimeout=15000", "username":"sqhc_rentcar", "password": "BzkmQM%O^U7Dy8X3", "maximumPoolSize":10, "minimumIdle":20, "connectionTimeout":3000, "leakDetectionThreshold":10000}</value>
</config>
2.spring-datasource.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="rentcarMaster" class="com.sq.driver.datasource.HikariDatasourceWrap">
<constructor-arg index="0" value="rentcar-master" />
</bean>
<bean id="rentcarSlave0" class="com.sq.driver.datasource.HikariDatasourceWrap">
<constructor-arg index="0" value="rentcar-slave" />
</bean>
<bean id="recordMaster" class="com.sq.driver.datasource.HikariDatasourceWrap">
<constructor-arg index="0" value="record-master" />
</bean>
<bean id="instantRobRecordMaster" class="com.sq.driver.datasource.HikariDatasourceWrap" >
<constructor-arg index="0" value="instant-record-maste" />
</bean>
<bean id="newdispatcherMaster" class="com.sq.driver.datasource.HikariDatasourceWrap">
<constructor-arg index="0" value="dispatcher-master" />
</bean>
<bean id="newdispatcherSlave0" class="com.sq.driver.datasource.HikariDatasourceWrap">
<constructor-arg index="0" value="dispatcher-slave" />
</bean>
<bean id="rentcarFactory" class="org.jfaster.mango.datasource.MasterSlaveDataSourceFactory">
<property name="name" value="dispatcher"/>
<property name="master" ref="rentcarMaster" />
<property name="slaves">
<list>
<ref bean="rentcarSlave0" />
</list>
</property>
</bean>
<bean id="recordFactory" class="org.jfaster.mango.datasource.SimpleDataSourceFactory">
<property name="name" value="dispatcher_record"/>
<property name="dataSource" ref="recordMaster" />
</bean>
<bean id="instantRobRecordFactory" class="org.jfaster.mango.datasource.SimpleDataSourceFactory">
<property name="name" value="dispatcher_instant_rob_record"/>
<property name="dataSource" ref="instantRobRecordMaster" />
</bean>
<bean id="newdispatcherFactory" class="org.jfaster.mango.datasource.MasterSlaveDataSourceFactory">
<property name="name" value="dispatcher_new"/>
<property name="master" ref="newdispatcherMaster" />
<property name="slaves">
<list>
<ref bean="newdispatcherSlave0" />
</list>
</property>
</bean>
<bean id="mango" class="org.jfaster.mango.operator.Mango" factory-method="newInstance">
<property name="dataSourceFactories">
<list>
<ref bean="rentcarFactory" />
<ref bean="recordFactory" />
<ref bean="instantRobRecordFactory"/>
<ref bean="newdispatcherFactory"/>
</list>
</property>
<!--
<property name="statMonitor">
<bean class="com.sq.dispatcher.monitor.DaoStatMonitor" >
<constructor-arg index="0" value="${dao.monitor.period}"/>
</bean>
</property> -->
</bean>
</beans>
3.数据源的预热
Map<String, HikariDatasourceWrap> datasources = context.getBeansOfType(HikariDatasourceWrap.class);
if(CollectionUtils.isNotEmpty(datasources.values())){
for (HikariDatasourceWrap datasourceWrap : datasources.values()) {
datasourceWrap.warmup();
}
}
4.HikariDatasourceWrap
public class HikariDatasourceWrap implements DataSource, Warmup {
private Logger logger = LoggerFactory.getLogger(HikariDatasourceWrap.class);
private final BaseNodeResource<HikariDataSource> datasourceNode;
private final String configKey;
private volatile DbHostInfo hostInfo;
public HikariDatasourceWrap(String configKey) {
this.configKey = configKey;
this.datasourceNode = BaseNodeResource.<HikariDataSource>newBuilder()
.withKey(configKey)
.withFactory(this::initDatasource)
.withCleanupConsumer(this::cleanup)
.withWaitStopPeriod(1000) //鍏抽棴鑰佺殑datasource鍓嶏紝鍏堢瓑1000ms锛岀瓑寰呮棫鏁版嵁鍙戦�佸畬鎴愩��
.addFactoryFailedListener(this::factoryFailListener)
.build();
}
private void factoryFailListener(String config, Throwable t) {
ConfigUtils.perfConfigFactoryFail(configKey, config, t);
}
private void cleanup(HikariDataSource old) {
logger.info("Cleanup old HikariDataSource {}", old.toString());
old.close();
}
private HikariDataSource initDatasource(String content) {
NamingHikariConfig config = JSON.parseObject(content, new TypeReference<NamingHikariConfig>() {
});
HikariDataSource dataSource = new HikariDataSource(config);
try {
this.hostInfo = DbUtils.extractDbInfo(config.getJdbcUrl(),
dataSource.getConnection()
.getMetaData()
.getDatabaseProductName());
} catch (SQLException e) {
logger.error("init datasource error", e);
throw new PerfDatasourceException(e);
}
if (!Strings.isNullOrEmpty(config.getName())) {
this.hostInfo.setName(config.getName());
}
return dataSource;
}
@Override
public Connection getConnection() throws SQLException {
return runWithPerf(d -> new ManagedConnection(hostInfo, d.getConnection()), "getConnection");
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return runWithPerf(d -> new ManagedConnection(hostInfo, d.getConnection(username, password)), "getConnection");
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return runWithPerf(d -> d.unwrap(iface), "unwrap");
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return runWithPerf(d -> d.isWrapperFor(iface), "isWrapperFor");
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return runWithPerf(HikariDataSource::getLogWriter, "getLogWriter");
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
HikariDataSource dataSource = this.datasourceNode.get();