[add] 修改了备用数据库切换

This commit is contained in:
LYC 2025-04-30 18:57:57 +08:00
parent bc01f0a680
commit 9cb88fbba3
5 changed files with 107 additions and 0 deletions

View File

@ -2,7 +2,9 @@ package com.waterquality.projectmanagement;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/*
@SpringBootApplication @SpringBootApplication
public class ProjectManagementApplication { public class ProjectManagementApplication {
@ -11,3 +13,11 @@ public class ProjectManagementApplication {
} }
} }
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class ProjectManagementApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectManagementApplication.class, args);
}
}

View File

@ -66,6 +66,7 @@ public class SecurityConfig {
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authz -> authz .authorizeHttpRequests(authz -> authz
.requestMatchers("/api/auth/**").permitAll() // 允许认证相关接口无需鉴权 .requestMatchers("/api/auth/**").permitAll() // 允许认证相关接口无需鉴权
.requestMatchers("/health").permitAll() // 允许认证相关接口无需鉴权
.requestMatchers("/api/**").authenticated() // 只有 /api/** 下的路由需要鉴权 .requestMatchers("/api/**").authenticated() // 只有 /api/** 下的路由需要鉴权
.requestMatchers("/static/**", "/css/**", "/js/**", "/assets/**", "/favicon.ico").permitAll() // 显式放通静态资源 .requestMatchers("/static/**", "/css/**", "/js/**", "/assets/**", "/favicon.ico").permitAll() // 显式放通静态资源
.requestMatchers("/", "/index.html").permitAll() // 放通 SPA 的入口页面 .requestMatchers("/", "/index.html").permitAll() // 放通 SPA 的入口页面

View File

@ -0,0 +1,58 @@
package com.waterquality.projectmanagement.config.database;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
// 主库数据源
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
// 备库数据源
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
// 动态数据源主备切换
@Primary
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource(
@Qualifier("masterDataSource") DataSource master,
@Qualifier("slaveDataSource") DataSource slave) {
DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceMap.put("master", master);
dataSourceMap.put("slave", slave);
// 默认使用主库
dynamicDataSource.setDefaultTargetDataSource(master);
dynamicDataSource.setTargetDataSources(dataSourceMap);
return dynamicDataSource;
}
// 配置事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dynamicDataSource) {
return new DataSourceTransactionManager(dynamicDataSource);
}
}

View File

@ -0,0 +1,20 @@
package com.waterquality.projectmanagement.config.database;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.concurrent.atomic.AtomicBoolean;
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
private static final AtomicBoolean isMasterAvailable = new AtomicBoolean(true);
@Override
protected Object determineCurrentLookupKey() {
// 默认路由到主库若主库不可用则切换到备库
return isMasterAvailable.get() ? "master" : "slave";
}
public static void setMasterAvailable(boolean available) {
isMasterAvailable.set(available);
}
}

View File

@ -0,0 +1,18 @@
package com.waterquality.projectmanagement.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.Map;
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity<Map<String, String>> health() {
// 简单返回 UP 状态
Map<String, String> status = Collections.singletonMap("status", "UP");
return ResponseEntity.ok(status);
}
}