fix(DataSourceServiceImpl):优化数据库连接池测试连接代码

dev
gtl 2024-05-01 14:42:53 +08:00
parent 5157792eb7
commit ffd058d717
3 changed files with 98 additions and 86 deletions

View File

@ -84,7 +84,8 @@ public class DataSourceController extends BaseController {
@PostMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<Integer> testConnect(@PathVariable("id") Long id) throws SQLException {
return Result.success(dataSourceService.testConnect(id)?200:500,dataSourceService.testConnect(id)?"连接成功":"连接失败");
dataSourceService.testConnect(id);
return Result.success(null,"连接成功");
}
/**

View File

@ -24,9 +24,8 @@ public interface DataSourceService extends IService<DataSource> {
*
*
* @param id id
* @return
*/
boolean testConnect(Long id) throws SQLException;
void testConnect(Long id) throws SQLException;
/**
*

View File

@ -5,10 +5,8 @@ import java.util.*;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.ObjUtils;
import com.ruoyi.common.core.utils.StringUtils;
@ -81,43 +79,28 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
/**
*
* @param id id
* @return /
*/
@Override
public boolean testConnect(Long id){
boolean result=true;
public void testConnect(Long id){
DataSource dataSource = this.getById(id);
DruidDataSource druidDatasource=null;
try {
druidDatasource = this.createDataSource(dataSource);
//如果为不可用修改为可用
if(dataSource.getStatus().equals("N")){
dataSource.setStatus("Y");
dataSource.setUpdateTime(new Date());
dataSource.setUpdateBy(SecurityUtils.getUsername());
this.updateById(dataSource);
}
druidDatasource.close();
} catch (Exception e) {
//连接失败,如果为可用修改为不可用
if(dataSource.getStatus().equals("Y")){
dataSource.setStatus("N");
dataSource.setUpdateTime(new Date());
dataSource.setUpdateBy(SecurityUtils.getUsername());
this.updateById(dataSource);
}
result=false;
DruidDataSource druidDataSource = this.createDataSource(dataSource);
//如果为不可用修改为可用
if(dataSource.getStatus().equals("N")){
dataSource.setStatus("Y");
dataSource.setUpdateTime(new Date());
dataSource.setUpdateBy(SecurityUtils.getUsername());
this.updateById(dataSource);
}
return result;
druidDataSource.close();
}
/**
* Druid
* @param dataSource
* @return Druid
* @throws SQLException
*/
public DruidDataSource createDataSource(DataSource dataSource) throws SQLException {
public DruidDataSource createDataSource(DataSource dataSource) {
DruidDataSource druidDataSource = null;
String driverType=null;
String url="jdbc:"+dataSource.getDatabaseType()+dataSource.getIp()+":"+dataSource.getPort();
if(dataSource.getDatabaseType().contains("mysql")){
@ -134,38 +117,63 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
url+=dataSource.getConnectionParameter()+";";
}
}
//手动创建数据源
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setName(dataSource.getId().toString());
druidDataSource.setDriverClassName(driverType);
druidDataSource.setUrl(url);
druidDataSource.setUsername(dataSource.getUsername());
druidDataSource.setPassword(dataSource.getPassword());
//设置连接配置
if(StringUtils.isNotEmpty(dataSource.getConnectionConfig())){
String[] configs = dataSource.getConnectionConfig().split(",");
for (String config : configs) {
String[] split = config.split("=");
if(config.contains("initNum")){
//初始化连接池大小
druidDataSource.setInitialSize(split.length>1&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):5);
}else if(config.contains("maxNum")){
//最大连接数
druidDataSource.setMaxActive(split.length>1&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):20);
}else if(config.contains("minIdle")){
//最小空闲数
druidDataSource.setMinIdle(split.length>1&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):5);
}else {
//获取连接最大等待时间,单位毫秒
druidDataSource.setMaxWait(split.length>1&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):6000);
//druid数据库连接池连接失败的情况下问题较多,需要先用JDBC测试一下可用性
try {
Class.forName(driverType);
DriverManager.setLoginTimeout(3);
Connection connection = DriverManager.getConnection(url, dataSource.getUsername(), dataSource.getPassword());
connection.close();
} catch (Exception e) {
//连接失败,如果为可用修改为不可用
if(dataSource.getStatus().equals("Y")){
dataSource.setStatus("N");
dataSource.setUpdateTime(new Date());
dataSource.setUpdateBy(SecurityUtils.getUsername());
this.updateById(dataSource);
}
throw new ServiceException("数据源连接失败");
}
try {
//手动创建数据源
druidDataSource = new DruidDataSource();
druidDataSource.setName(dataSource.getId().toString());
druidDataSource.setDriverClassName(driverType);
druidDataSource.setUrl(url);
druidDataSource.setUsername(dataSource.getUsername());
druidDataSource.setPassword(dataSource.getPassword());
//设置连接配置
if(StringUtils.isNotEmpty(dataSource.getConnectionConfig())){
String[] configs = dataSource.getConnectionConfig().split(",");
for (String config : configs) {
String[] split = config.split("=");
if(config.contains("initNum")){
//初始化连接池大小
druidDataSource.setInitialSize(split.length>1&&!split[1].equals("null")&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):5);
}else if(config.contains("maxNum")){
//最大连接数
druidDataSource.setMaxActive(split.length>1&&!split[1].equals("null")&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):20);
}else if(config.contains("minIdle")){
//最小空闲数
druidDataSource.setMinIdle(split.length>1&&!split[1].equals("null")&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):5);
}else {
//获取连接最大等待时间,单位毫秒
druidDataSource.setMaxWait(split.length>1&&!split[1].equals("null")&&StringUtils.isNotEmpty(split[1])?Convert.toInt(split[1]):4000);
}
}
}
String validationQuery = "select 1";
//申请连接时执行validationQuery检测连接是否有效防止取到的连接不可用
druidDataSource.setTestOnBorrow(true);
druidDataSource.setValidationQuery(validationQuery);
//防止DruidDataSource一直尝试获取连接,导致服务卡死
druidDataSource.setConnectionErrorRetryAttempts(0);
druidDataSource.setBreakAfterAcquireFailure(true);
druidDataSource.setTimeBetweenEvictionRunsMillis(0);
druidDataSource.setConnectTimeout(2000);
druidDataSource.init();
} catch (Exception e) {
throw new RuntimeException(e);
}
String validationQuery = "select 1";
//申请连接时执行validationQuery检测连接是否有效防止取到的连接不可用
druidDataSource.setTestOnBorrow(true);
druidDataSource.setValidationQuery(validationQuery);
druidDataSource.init();
return druidDataSource;
}
@ -196,12 +204,11 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
dataSource.setTableTotal(result.getInt("tableTotal"));
dataSource.setRecordsTotal(result.getInt("recordsTotal"));
}
ExecutorService executorService = Executors.newCachedThreadPool();
//异步同步表结构并等待所有任务结束
CompletableFuture.supplyAsync(() -> {
this.SynchronousTableStructure(druidDatasource, dataSource);
return "end";
}, executorService).get();
}).get();
//修改数据
this.updateById(dataSource);
result.close();
@ -219,7 +226,7 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
public void SynchronousTableStructure(DruidDataSource druidDatasource,DataSource dataSource){
try {
List<CompletableFuture<String>> runAsyncList=new ArrayList<>();
DruidPooledConnection connection = druidDatasource.getConnection();
Connection connection = druidDatasource.getConnection();
ResultSet tables = connection.getMetaData().getTables(connection.getCatalog(), "dbo", "%", new String[] { "TABLE" });
while (tables.next()) {
String tableName = tables.getString("TABLE_NAME");
@ -232,15 +239,18 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
}
resultSet.close();
TableInfo tableInfo = TableInfo.builder().name(tableName).comment(comment).recordsTotal(recordsTotal).dataSourceId(dataSource.getId()).build();
//可能同步过,先删除
TableInfo one = tableInfoService.getOne(new LambdaQueryWrapper<TableInfo>()
.eq(TableInfo::getName, tableName)
.eq(TableInfo::getDataSourceId, dataSource.getId()));
if(Objects.nonNull(one)){
tableInfoService.removeById(one.getId());
columnInfoService.remove(new LambdaQueryWrapper<ColumnInfo>()
.eq(ColumnInfo::getTableId,one.getId()));
}
//异步添加表数据
CompletableFuture.runAsync(()->{
//可能同步过,先删除
TableInfo one = tableInfoService.getOne(new LambdaQueryWrapper<TableInfo>()
.eq(TableInfo::getName, tableName)
.eq(TableInfo::getDataSourceId, dataSource.getId()));
if(Objects.nonNull(one)){
tableInfoService.removeById(one.getId());
columnInfoService.remove(new LambdaQueryWrapper<ColumnInfo>()
.eq(ColumnInfo::getTableId,one.getId()));
}
});
//添加
tableInfoService.save(tableInfo);
//异步存储表数据
@ -270,7 +280,7 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
//声明资产模型数据空集合
List<AssetModelData> moduleDataList=new ArrayList<>();
try {
DruidPooledConnection connection = druidDatasource.getConnection();
Connection connection = druidDatasource.getConnection();
ResultSet columns = connection.getMetaData().getColumns(connection.getCatalog(), null, tableName, "%");
ResultSet primaryKeys = connection.getMetaData().getPrimaryKeys(connection.getCatalog(), null, tableName);
String primaryKeyName=null;
@ -337,21 +347,23 @@ public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSou
.type(javaType).value(string==null?"null":string).tableId(tableId).build());
}
}
//批量添加字段信息
columnInfoService.saveBatch(list);
//查询是否已有资产模型数据
List<Long> longList = assetModuleDataService.list(new LambdaQueryWrapper<AssetModelData>().eq(AssetModelData::getTableId, tableId))
.stream().map(AssetModelData::getId).toList();
if(!longList.isEmpty()){
//批量删除
assetModuleDataService.removeBatchByIds(longList);
}
//批量添加
assetModuleDataService.saveBatch(moduleDataList);
CompletableFuture.runAsync(()->{
//批量添加字段信息
columnInfoService.saveBatch(list);
//查询是否已有资产模型数据
List<Long> longList = assetModuleDataService.list(new LambdaQueryWrapper<AssetModelData>().eq(AssetModelData::getTableId, tableId))
.stream().map(AssetModelData::getId).toList();
if(!longList.isEmpty()){
//批量删除
assetModuleDataService.removeBatchByIds(longList);
}
//批量添加
assetModuleDataService.saveBatch(moduleDataList);
});
//关闭连接
if(sqlServerSet!=null){
sqlServerSet.close();
}
//关闭连接
columns.close();
resultSet.close();
connection.close();