add
This commit is contained in:
@ -45,8 +45,10 @@ public class BackupDatasourceContext {
|
||||
* @param list 数据源集合
|
||||
*/
|
||||
private void set(String tenantId, List<DynamicDataSource> list) {
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
redisTemplate.opsForValue().set(BACKUP_DATASOURCE_KET + tenantId, list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加租户备用数据源
|
||||
@ -59,6 +61,14 @@ public class BackupDatasourceContext {
|
||||
if (CollUtil.isEmpty(dataSourceList)) {
|
||||
set(dataSource.getTenantId(), ListUtil.toList(dataSource));
|
||||
} 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);
|
||||
}
|
||||
@ -69,13 +79,14 @@ public class BackupDatasourceContext {
|
||||
List<DynamicDataSource> dataSourceList = get(dynamicDataSource.getTenantId());
|
||||
if (CollUtil.isNotEmpty(dataSourceList)) {
|
||||
for (DynamicDataSource dataSource : dataSourceList) {
|
||||
if (dataSource.getUrl().equals(dynamicDataSource.getUrl())) {
|
||||
if (dataSource.getUrl().equals(dynamicDataSource.getUrl())
|
||||
&& dataSource.getTenantId().equals(dynamicDataSource.getTenantId())) {
|
||||
dataSourceList.remove(dataSource);
|
||||
set(dataSource.getTenantId(), dataSourceList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
set(dynamicDataSource.getTenantId(), dataSourceList);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,11 +110,11 @@ public class BackupDatasourceContext {
|
||||
for (DynamicDataSource dynamicDataSource : dataSourceList) {
|
||||
if (dataSource.getDatasourceId().equals(dynamicDataSource.getDatasourceId())) {
|
||||
dataSourceList.remove(dynamicDataSource);
|
||||
dataSourceList.add(dataSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dataSourceList.add(dataSource);
|
||||
set(dataSource.getTenantId(), dataSourceList);
|
||||
}
|
||||
}
|
||||
|
@ -60,4 +60,13 @@ public class PrimaryDatasourceContext {
|
||||
public static void remove(String tenantId) {
|
||||
PRIMARY_DATASOURCE_MAP.remove(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
public static boolean exist(String tenantId) {
|
||||
return PRIMARY_DATASOURCE_MAP.containsKey(tenantId);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 动态数据源实体
|
||||
@ -76,4 +77,5 @@ public class DynamicDataSource implements Serializable {
|
||||
* 服务器SN
|
||||
*/
|
||||
private String serverSn;
|
||||
|
||||
}
|
||||
|
@ -142,10 +142,8 @@ public class OnlineDatasourceMonitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
Integer backupIndex = null;
|
||||
|
||||
for (int i = 0; i < dataSources.size(); i++) {
|
||||
DynamicDataSource backDatasource = dataSources.get(i);
|
||||
DynamicDataSource backDynamicDataSource = null;
|
||||
for (DynamicDataSource backDatasource : dataSources) {
|
||||
Object dynamicDataSource = DatasourceUtil.buildDataSource(tenantId, backDatasource);
|
||||
// 不是空,说明备用数据源有用
|
||||
if (Objects.nonNull(dynamicDataSource)) {
|
||||
@ -154,23 +152,20 @@ public class OnlineDatasourceMonitor {
|
||||
redisService.convertAndSend("test", JSONUtil.toJsonStr(backDatasource));
|
||||
// 延迟1s钟 等待其他服务器完成切换
|
||||
ThreadUtil.sleep(1000);
|
||||
backupIndex = i;
|
||||
backDynamicDataSource = backDatasource;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.nonNull(backupIndex)) {
|
||||
// 切换成功
|
||||
DynamicDataSource dynamicDataSource = dataSources.get(backupIndex);
|
||||
if (Objects.nonNull(backDynamicDataSource)) {
|
||||
// 更改数据库中该数据源为主要数据源
|
||||
if (Objects.nonNull(dynamicDataSource.getTenantId()) && !TenantConstant.DEFAULT_TENANT_ID.equals(dynamicDataSource.getTenantId())) {
|
||||
if (Objects.nonNull(backDynamicDataSource.getTenantId()) && !TenantConstant.DEFAULT_TENANT_ID.equals(backDynamicDataSource.getTenantId())) {
|
||||
// 添加到待处理任务中
|
||||
addWaitUpdateDatasourceStatus(dynamicDataSource.getTenantId(), dynamicDataSource.getDatasourceId());
|
||||
addWaitUpdateDatasourceStatus(backDynamicDataSource.getTenantId(), backDynamicDataSource.getDatasourceId());
|
||||
}
|
||||
// 备用数据源集合删除该数据源
|
||||
dataSources.remove((int) backupIndex);
|
||||
backupDatasourceContext.addBackupMap(tenantId, dataSources);
|
||||
log.info("租户:[{}]切换备用数据源成功, 现主数据ID: {}", tenantId, dynamicDataSource.getDatasourceId());
|
||||
backupDatasourceContext.deleteBackupMap(backDynamicDataSource);
|
||||
log.info("租户:[{}]切换备用数据源成功, 现主数据ID: {}", tenantId, backDynamicDataSource.getDatasourceId());
|
||||
return true;
|
||||
} else {
|
||||
log.error("租户:[{}]切换备用数据源失败, 原因: 备用数据源均无效", tenantId);
|
||||
|
@ -32,6 +32,8 @@ public class JdbcUtil {
|
||||
Connection conn = null;
|
||||
try {
|
||||
Class.forName(driver);
|
||||
// 设置两秒延时 默认10s
|
||||
DriverManager.setLoginTimeout(2);
|
||||
//建立连接
|
||||
conn = DriverManager.getConnection(url, username, password);
|
||||
return true;
|
||||
|
@ -3,14 +3,17 @@ package com.qiaoba.module.tenant.filter;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.qiaoba.api.tenant.entity.SysTenant;
|
||||
import com.qiaoba.api.tenant.enums.TenantModeEnum;
|
||||
import com.qiaoba.api.tenant.enums.TenantStatusEnum;
|
||||
import com.qiaoba.api.tenant.utils.TenantUtil;
|
||||
import com.qiaoba.common.base.code.DatasourceErrorCode;
|
||||
import com.qiaoba.common.base.code.TenantErrorCode;
|
||||
import com.qiaoba.common.base.constant.BaseConstant;
|
||||
import com.qiaoba.common.base.constant.TenantConstant;
|
||||
import com.qiaoba.common.base.context.BaseContext;
|
||||
import com.qiaoba.common.base.order.FilterOrder;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
|
||||
import com.qiaoba.common.database.context.PrimaryDatasourceContext;
|
||||
import com.qiaoba.common.web.util.ResponseUtil;
|
||||
import com.qiaoba.common.web.util.UriUtil;
|
||||
import com.qiaoba.module.tenant.service.SysTenantService;
|
||||
@ -61,6 +64,7 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
|
||||
try {
|
||||
log.debug("Start run DynamicDataSourceFilter, Uri: {}", request.getRequestURI());
|
||||
String tenantId = request.getHeader(TenantConstant.HEADER_KEY_TENANT);
|
||||
|
||||
// 主系统 or 登录入口获取租户列表
|
||||
if (TenantConstant.DEFAULT_TENANT_ID.equals(tenantId) || TenantConstant.LOGIN_TENANT_LIST_URI.equals(request.getRequestURI())) {
|
||||
dynamicDataSourceConfig.setDefaultSetting();
|
||||
@ -113,6 +117,14 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查租户数据源是否正常
|
||||
if (TenantModeEnum.isDatasource(sysTenant.getMode())
|
||||
&& !PrimaryDatasourceContext.exist(sysTenant.getTenantId())) {
|
||||
// 无主数据
|
||||
log.debug("租户数据源不可用, 租户ID: {}", sysTenant.getTenantId());
|
||||
ResponseUtil.errorAuth(response, DatasourceErrorCode.CONNECT_ERROR.getCode(), DatasourceErrorCode.CONNECT_ERROR.getMsg());
|
||||
return true;
|
||||
}
|
||||
if (TenantStatusEnum.isDisable(sysTenant.getStatus())) {
|
||||
// 封禁状态
|
||||
log.debug("租户已封禁, 租户ID: {}", sysTenant.getTenantId());
|
||||
|
Reference in New Issue
Block a user