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