This commit is contained in:
2023-07-21 17:30:56 +08:00
parent aa73abd136
commit 06f447cb98
6 changed files with 209 additions and 59 deletions

View File

@ -26,6 +26,7 @@ import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 多数据源配置
@ -107,10 +108,8 @@ public class DynamicDataSourceConfig {
// 其他数据源备用
dataSources.removeAll(delDataSources);
for (DynamicDataSource dynamicDataSource : dataSources) {
dynamicDataSource.setTenantId(TenantConstant.DEFAULT_TENANT_ID);
}
backupDatasourceContext.addBackupMap(TenantConstant.DEFAULT_TENANT_ID, dataSources);
Set<DynamicDataSource> dataSourceSet = dataSources.stream().peek(dataSource -> dataSource.setTenantId(TenantConstant.DEFAULT_TENANT_ID)).collect(Collectors.toSet());
backupDatasourceContext.addBackupMap(TenantConstant.DEFAULT_TENANT_ID, dataSourceSet);
// 刷新数据源
this.dataSource.freshDataSource(PrimaryDatasourceContext.getAll());
}
@ -140,7 +139,7 @@ public class DynamicDataSourceConfig {
}
// 备用数据源
dataSources.removeAll(delDataSources);
backupDatasourceContext.addBackupMap(tenantId, dataSources);
backupDatasourceContext.addBackupMap(tenantId, new HashSet<>(dataSources));
TENANT_IDS.add(tenantId);
}

View File

@ -1,17 +1,17 @@
package com.qiaoba.common.database.context;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import com.qiaoba.common.database.entity.DynamicDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
/**
* 备用(未在使用)数据源
* 备用(未在使用)数据源
*
* @author ailanyin
* @version 1.0
@ -34,8 +34,8 @@ public class BackupDatasourceContext {
* @param tenantId 租户ID
* @return 数据源集合
*/
public List<DynamicDataSource> get(String tenantId) {
return (List<DynamicDataSource>) redisTemplate.opsForValue().get(BACKUP_DATASOURCE_KET + tenantId);
public Set<DynamicDataSource> get(String tenantId) {
return (Set<DynamicDataSource>) redisTemplate.opsForValue().get(BACKUP_DATASOURCE_KET + tenantId);
}
/**
@ -44,7 +44,7 @@ public class BackupDatasourceContext {
* @param tenantId 租户ID
* @param list 数据源集合
*/
private void set(String tenantId, List<DynamicDataSource> list) {
private void set(String tenantId, Set<DynamicDataSource> list) {
if (CollUtil.isNotEmpty(list)) {
redisTemplate.opsForValue().set(BACKUP_DATASOURCE_KET + tenantId, list);
}
@ -53,40 +53,34 @@ public class BackupDatasourceContext {
/**
* 添加租户备用数据源
*
* @param dataSource 数据源
* @param dynamicDataSource 数据源
*/
public void addBackupMap(DynamicDataSource dataSource) {
log.info("添加租户备用数据源, 租户ID:{}, 数据源IP:{}", dataSource.getTenantId(), dataSource.getUrl());
List<DynamicDataSource> dataSourceList = get(dataSource.getTenantId());
if (CollUtil.isEmpty(dataSourceList)) {
set(dataSource.getTenantId(), ListUtil.toList(dataSource));
public void addBackupMap(DynamicDataSource dynamicDataSource) {
log.info("添加租户备用数据源, 租户ID:{}, 数据源IP:{}", dynamicDataSource.getTenantId(), dynamicDataSource.getUrl());
Set<DynamicDataSource> dataSourceSet = get(dynamicDataSource.getTenantId());
if (CollUtil.isEmpty(dataSourceSet)) {
Set<DynamicDataSource> set = new HashSet<>();
set.add(dynamicDataSource);
set(dynamicDataSource.getTenantId(), set);
} else {
for (DynamicDataSource dynamicDataSource : dataSourceList) {
// 删除原来的
if (dataSource.getUrl().equals(dynamicDataSource.getUrl())
&& dataSource.getTenantId().equals(dynamicDataSource.getTenantId())) {
dataSourceList.remove(dataSource);
break;
}
}
dataSourceList.add(dataSource);
set(dataSource.getTenantId(), dataSourceList);
dataSourceSet.add(dynamicDataSource);
set(dynamicDataSource.getTenantId(), dataSourceSet);
}
}
public void deleteBackupMap(DynamicDataSource dynamicDataSource) {
log.info("移除租户备用数据源, 租户ID:{}, 数据源IP:{}", dynamicDataSource.getTenantId(), dynamicDataSource.getUrl());
List<DynamicDataSource> dataSourceList = get(dynamicDataSource.getTenantId());
if (CollUtil.isNotEmpty(dataSourceList)) {
for (DynamicDataSource dataSource : dataSourceList) {
if (dataSource.getUrl().equals(dynamicDataSource.getUrl())
&& dataSource.getTenantId().equals(dynamicDataSource.getTenantId())) {
dataSourceList.remove(dataSource);
break;
}
}
Set<DynamicDataSource> dataSourceSet = get(dynamicDataSource.getTenantId());
if (CollUtil.isNotEmpty(dataSourceSet)) {
dataSourceSet.remove(dynamicDataSource);
}
if (CollUtil.isEmpty(dataSourceSet)) {
// 删除
redisTemplate.delete(BACKUP_DATASOURCE_KET + dynamicDataSource.getTenantId());
} else {
set(dynamicDataSource.getTenantId(), dataSourceSet);
}
set(dynamicDataSource.getTenantId(), dataSourceList);
}
/**
@ -95,7 +89,7 @@ public class BackupDatasourceContext {
* @param tenantId 租户ID
* @param dataSources 数据源集合
*/
public void addBackupMap(String tenantId, List<DynamicDataSource> dataSources) {
public void addBackupMap(String tenantId, Set<DynamicDataSource> dataSources) {
set(tenantId, dataSources);
}
@ -105,16 +99,16 @@ public class BackupDatasourceContext {
* @param dataSource 数据源
*/
public void updateBackupMap(DynamicDataSource dataSource) {
List<DynamicDataSource> dataSourceList = get(dataSource.getTenantId());
if (CollUtil.isNotEmpty(dataSourceList)) {
for (DynamicDataSource dynamicDataSource : dataSourceList) {
Set<DynamicDataSource> dataSourceSet = get(dataSource.getTenantId());
if (CollUtil.isNotEmpty(dataSourceSet)) {
for (DynamicDataSource dynamicDataSource : dataSourceSet) {
if (dataSource.getDatasourceId().equals(dynamicDataSource.getDatasourceId())) {
dataSourceList.remove(dynamicDataSource);
dataSourceSet.remove(dynamicDataSource);
break;
}
}
dataSourceSet.add(dataSource);
set(dataSource.getTenantId(), dataSourceSet);
}
dataSourceList.add(dataSource);
set(dataSource.getTenantId(), dataSourceList);
}
}

View File

@ -1,7 +1,6 @@
package com.qiaoba.common.database.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -16,7 +15,6 @@ import java.util.Objects;
* @since 2023-06-13 20:24:31
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DynamicDataSource implements Serializable {
@ -78,4 +76,23 @@ public class DynamicDataSource implements Serializable {
*/
private String serverSn;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DynamicDataSource that = (DynamicDataSource) o;
return url.equals(that.url) &&
tenantId.equals(that.tenantId);
}
@Override
public int hashCode() {
return Objects.hash(url, tenantId);
}
}

View File

@ -136,7 +136,7 @@ public class OnlineDatasourceMonitor {
*/
private Boolean backToPrimary(String tenantId) {
// 备用数据源
List<DynamicDataSource> dataSources = backupDatasourceContext.get(tenantId);
Set<DynamicDataSource> dataSources = backupDatasourceContext.get(tenantId);
if (CollUtil.isEmpty(dataSources)) {
log.error("租户:[{}]切换备用数据源失败, 原因: 没有备用数据源", tenantId);
return false;