멀티 테넌시(Multi-tenancy): Spring Data JPA로 여러 데이터 소스 관리
여러 데이터 소스를 관리할 수 있는 서비스를 만들어야 합니다.이러한 데이터 소스는 앱을 처음 실행할 때 실제로 엔드포인트가 새로운 데이터베이스를 생성할 때 반드시 존재하는 것은 아니며, 저는 이러한 데이터 소스로 전환하여 데이터를 생성할 수 있기를 원합니다.
예를 들어, 제가 A, B, C 등 3개의 데이터베이스를 가지고 있다고 가정하고, 앱을 시작하고, D를 생성하는 엔드포인트를 사용하고, D를 사용하고 싶습니다.
그게 가능한가요?
다른 데이터 소스가 있는 경우 다른 데이터 소스로 전환하는 방법은 알고 있지만 현재로서는 요청을 가능하게 해 줄 솔루션을 찾을 수 없습니다.무슨 생각 있어요?
감사해요.
Spring Boot로 멀티 테넌시(Multi-tenancy)를 구현하려면 AbstractRoutingDataSource를 모든 '테넌시 데이터베이스'에 대한 기본 DataSource 클래스로 사용할 수 있습니다.
재정의해야 하는 CurrentLookupKey를 결정하는 추상적인 방법이 하나 있습니다.그것은 말해줍니다.AbstractRoutingDataSource
현재 작업할 테넌트 데이터 소스를 제공해야 합니다.다중 스레드 환경에서 작동하므로 선택한 테넌트의 정보를ThreadLocal
변수.
그AbstractRoutingDataSource
테넌트 데이터 소스의 정보를 개인에 저장합니다.Map<Object, Object> targetDataSources
. 이 맵의 키는 테넌트 식별자(예: String type)와 테넌트 데이터 소스의 값입니다.테넌트 데이터 소스를 이 맵에 배치하려면 해당 세터를 사용해야 합니다.setTargetDataSources
.
그AbstractRoutingDataSource
메서드와 함께 설정해야 하는 'default' 데이터 소스가 없으면 작동하지 않습니다.setDefaultTargetDataSource(Object defaultTargetDataSource)
.
테넌트 데이터 소스와 기본 데이터 소스를 설정한 후 메소드를 호출해야 합니다.afterPropertiesSet()
말로 전하다AbstractRoutingDataSource
상태를 업데이트합니다.
따라서 'Multi Tenant Manager' 클래스는 다음과 같습니다.
@Configuration
public class MultiTenantManager {
private final ThreadLocal<String> currentTenant = new ThreadLocal<>();
private final Map<Object, Object> tenantDataSources = new ConcurrentHashMap<>();
private final DataSourceProperties properties;
private AbstractRoutingDataSource multiTenantDataSource;
public MultiTenantManager(DataSourceProperties properties) {
this.properties = properties;
}
@Bean
public DataSource dataSource() {
multiTenantDataSource = new AbstractRoutingDataSource() {
@Override
protected Object determineCurrentLookupKey() {
return currentTenant.get();
}
};
multiTenantDataSource.setTargetDataSources(tenantDataSources);
multiTenantDataSource.setDefaultTargetDataSource(defaultDataSource());
multiTenantDataSource.afterPropertiesSet();
return multiTenantDataSource;
}
public void addTenant(String tenantId, String url, String username, String password) throws SQLException {
DataSource dataSource = DataSourceBuilder.create()
.driverClassName(properties.getDriverClassName())
.url(url)
.username(username)
.password(password)
.build();
// Check that new connection is 'live'. If not - throw exception
try(Connection c = dataSource.getConnection()) {
tenantDataSources.put(tenantId, dataSource);
multiTenantDataSource.afterPropertiesSet();
}
}
public void setCurrentTenant(String tenantId) {
currentTenant.set(tenantId);
}
private DriverManagerDataSource defaultDataSource() {
DriverManagerDataSource defaultDataSource = new DriverManagerDataSource();
defaultDataSource.setDriverClassName("org.h2.Driver");
defaultDataSource.setUrl("jdbc:h2:mem:default");
defaultDataSource.setUsername("default");
defaultDataSource.setPassword("default");
return defaultDataSource;
}
}
간단한 설명:
지도를
tenantDataSources
로컬 테넌트 데이터 소스 스토리지로,setTargetDataSources
세터;DataSourceProperties properties
테넌트 데이터베이스의 데이터베이스 드라이버 클래스 이름을 가져오는 데 사용됩니다.spring.datasource.driverClassName
'application.properties'(예:org.postgresql.Driver
);방법
addTenant
새 테넌트와 해당 데이터 소스를 로컬 테넌트 데이터 소스 스토리지에 추가하는 데 사용됩니다.이 방법 덕분에 바로 할 수 있습니다.afterPropertiesSet()
;방법
setCurrentTenant(String tenantId)
지정된 테넌트의 데이터 소스를 '전환'하는 데 사용됩니다.예를 들어 REST 컨트롤러에서 데이터베이스 작업 요청을 처리할 때 이 방법을 사용할 수 있습니다.요청에는 예를 들어 'tenantId'가 포함되어야 합니다.X-TenantId
우리가 검색하고 이 방법에 넣을 수 있는 헤더.defaultDataSource()
는 작동 중인 SQL 서버에서 기본 데이터베이스를 사용하지 않도록 인메모리 H2 데이터베이스로 구축됩니다.
참고: 설정해야 합니다.spring.jpa.hibernate.ddl-auto
에 매개 변수를 지정합니다.none
Hibernate 데이터베이스 스키마를 변경하지 않도록 설정합니다.테넌트 데이터베이스 스키마를 미리 생성해야 합니다.
이 수업의 전체 예시와 더 많은 것들은 내 레포에서 찾을 수 있습니다.
업데이트됨
이 분기에서는 속성 파일 대신 테넌트 DB 속성을 저장하기 위해 전용 데이터베이스를 사용하는 예를 보여 줍니다(아래 @MarcoGustavo의 질문 참조).
언급URL : https://stackoverflow.com/questions/49759672/multi-tenancy-managing-multiple-datasources-with-spring-data-jpa
'programing' 카테고리의 다른 글
Oracle sql null 값이 선택되지 않았습니다. (0) | 2023.10.02 |
---|---|
ESNext란? (0) | 2023.10.02 |
Test if an object is an empty object in a AngularJS template (0) | 2023.10.02 |
Mobile Web HTML5 Framework 선택하기 (0) | 2023.10.02 |
"안드로이드:백업 허용"이란 무엇입니까? (0) | 2023.10.02 |