GW LABS

Spring Boot Multi DataSource 본문

Programming/Java

Spring Boot Multi DataSource

GeonWoo Kim 2021. 12. 14. 20:40

 

이번 포스팅에서는 스프링 부트에서 여러 DataSource를 구성하는 방법을 소개한다. 보통의 경우 스프링 부트에서 DataSource는 하나로 유지해도 충분할 것이다. MSA 아키텍처가 유행하고 있고, 이에 따라 각각의 작은 API 프로젝트들이 하나의 DB만 바라보면 충분하기 때문이다. 그러나 특별한 상황에서 한 프로젝트에서 여러 DataSource가 필요한 경우가 있다. 이러한 Multi Datasource 같은 경우에도 구성방법은 어렵지 않다. 실수하기 쉬운 부분을 여기에 정리하려고 한다. 

 


 

여러 개의 DataSource가 필요한 상황

  • 마이그레이션
    • 마이그레이션 작업을 스프링 부트를 이용해서 진행해야 할 때 여러 DataSource를 설정하여 작업이 필요하다.
  • API없이 하나 이상의 DB처리
    • 별도 API가 없이 하나 이상의 데이터베이스에 연결하여 작업을 진행해야 할 경우도 있을 수 있다. API 구현이 안되어 있는 상황에서 배치 프로세스같은 것이 필요한 경우에 여러 DataSource 설정을 통해서 문제를 해결할 수 있을 것이다.

 

여러 개의 DataSource 설정방법

기본적인 설정은 크게 다르지 않으나, 스프링 부트 properties 파일과 config 설정파일에서 신경써줘야 하는 부분이 생긴다. properties에서 각각의 Datasource 마다 namespace가 추가되고(예제에서 first, second) 그 아래에 datasource에 대한 설정을 추가하는 방식이다.

config 설정파일에서는 Datasource를 각각 네이밍하여 Bean을 선택할 수 있도록 구성했다. 주의할 점은 공통으로 사용할 설정들(hikari 등)도 각각 Datasource 설정에 적용을 해줘야 한다는 점이다. 아래의 예제에서 처럼 기본설정(한 개의 Datasource)과 Multi Datasource 설정을 비교해보면 이해가 쉬울 것이다.

 

 

  • properties
    • 기본 DataSource 설정
      • spring.h2.console.enabled=true
        
        # 공통설정
        spring.datasource.hikari.max-lifetime=100000
        spring.datasource.hikari.maximum-pool-size=10
        
        spring.datasource.jdbc-url=jdbc:h2:mem:first
        spring.datasource.driverClassName=org.h2.Driver
        spring.datasource.username=first
        spring.datasource.password=
        
        # 로깅레벨
        logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
    • Multi DataSource 설정
      • spring.h2.console.enabled=true
        
        # 공통설정
        spring.datasource.hikari.max-lifetime=100000
        spring.datasource.hikari.maximum-pool-size=10
        
        # 첫번째 Datasource 설정
        spring.first.datasource.jdbc-url=jdbc:h2:mem:first
        spring.first.datasource.driverClassName=org.h2.Driver
        spring.first.datasource.username=first
        spring.first.datasource.password=
        
        # 두번째 Datasource 설정
        spring.second.datasource.jdbc-url=jdbc:h2:mem:second
        spring.second.datasource.driverClassName=org.h2.Driver
        spring.second.datasource.username=second
        spring.second.datasource.password=
        
        # 로깅레벨
        logging.level.com.zaxxer.hikari.HikariConfig=DEBUG

 

 

  • config
    • 기본 DataSource 설정
      • 스프링부트 properties를 사용한다면 별도 config 자바 파일은 필요없다.
    • Multi DataSource 설정
      • @Configuration
        public class CommonConfig {
            @Bean(name = "commonHikariConfig")
            @ConfigurationProperties(prefix = "spring.datasource.hikari")
            public HikariConfig commonHikariConfig() {
                return new HikariConfig();
            }
        }
      • @Slf4j
        @Configuration
        @RequiredArgsConstructor
        public class FirstDataSourceConfig {
        
            private final CommonConfig commonConfig;
        
            @Bean(name = "firstDataSource")
            @ConfigurationProperties(prefix = "spring.first.datasource")
            public DataSource firstDataSource() {
                HikariDataSource firstDataSource = new HikariDataSource();
        
                // 공통설정 적용
                firstDataSource.setMaxLifetime(commonConfig.commonHikariConfig().getMaxLifetime());
                firstDataSource.setMaximumPoolSize(commonConfig.commonHikariConfig().getMaximumPoolSize());
                return firstDataSource;
            }
        
            @Bean(name = "firstJdbcTemplate")
            public JdbcTemplate firstJdbcTemplate(@Qualifier("firstDataSource") DataSource firstDataSource) {
                return new JdbcTemplate(firstDataSource);
            }
        
            /**
             * H2 DB 초기화 스크립트 실행을 위한
             * DataSourceInitializer 정의
             * @param datasource
             * @return dataSourceInitializer
             */
            @Bean
            public DataSourceInitializer firstDataSourceInitializer(@Qualifier("firstDataSource") DataSource datasource) {
                ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
                resourceDatabasePopulator.addScript(new ClassPathResource("first-schema.sql"));
        
                DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
                dataSourceInitializer.setDataSource(datasource);
                dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
                return dataSourceInitializer;
            }
        }
      • @Slf4j
        @Configuration
        @RequiredArgsConstructor
        public class SecondDataSourceConfig {
        
            private final CommonConfig commonConfig;
        
            @Bean(name = "secondDataSource")
            @ConfigurationProperties(prefix = "spring.second.datasource")
            public DataSource secondDataSource() {
                HikariDataSource secondDataSource = new HikariDataSource();
        
                // 공통설정 적용
                secondDataSource.setMaxLifetime(commonConfig.commonHikariConfig().getMaxLifetime());
                secondDataSource.setMaximumPoolSize(commonConfig.commonHikariConfig().getMaximumPoolSize());
                return secondDataSource;
            }
        
            @Bean(name = "secondJdbcTemplate")
            public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource secondDataSource) {
                return new JdbcTemplate(secondDataSource);
            }
        
            /**
             * H2 DB 초기화 스크립트 실행을 위한
             * DataSourceInitializer 정의
             * @param datasource
             * @return dataSourceInitializer
             */
            @Bean
            public DataSourceInitializer secondDataSourceInitializer(@Qualifier("secondDataSource") DataSource datasource) {
                ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
                resourceDatabasePopulator.addScript(new ClassPathResource("second-schema.sql"));
        
                DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
                dataSourceInitializer.setDataSource(datasource);
                dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
                return dataSourceInitializer;
            }
        }

 

 

위와 같은 설정을 적용하고 mybatis 혹은 JDBCTemplate 같은 곳에 사용하고자 하는 Datasource를 적용해주면 여러 DB Connection을 제어할 수 있게 된다. 마지막으로 전체 예제 소스링크를 첨부한다.

 

 

GitHub - youlive789/spring-lab: A spring boot study project with cook book style.

A spring boot study project with cook book style. Contribute to youlive789/spring-lab development by creating an account on GitHub.

github.com

 

 

'Programming > Java' 카테고리의 다른 글

Spring Boot Multi-threaded JDBCTemplate  (0) 2021.12.15
Comments