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