반응형

RoutingDataSource란?

동적으로 다수의 dataSource를 연결할 수 있게 도와주는 클래스

 

- 사용이유

프로그램 사용자가 늘어남에 따라 하나의 데이터베이스에 읽기/쓰기 작업이 집중되면

부하가 늘어나고 성능 저하가 일어날 수 있으므로 트래픽 분산을 위해 사용

 

외부의 DB링크 테이블 조회시 ConnectionPool의 개수가 다수이면 connection이 중간에 끊기는 현상이 발생

링크 테이블 조회시에만 ConnectionPool의 개수가 1개인 DB에 붙어 조회하기 위해 사용하기도 함

 

 

# DataSource에 대한 Routing 정책을 결정하는 클래스로 Spring 에서 제공

1. AbstractRoutingDataSource클래스를 상속하여 구현

해당 클래스의 targetDateSources 필드를 통해 어떠한 key 값으로 DataSource를 선택할지 결정한다.

 

2. determineCurrentLookupKey() 메소드를 Override하여 구현

LookUpKey에 해당하는 dataSource가 있다면, 해당 Datasource를 선택하여 가져오고 존재하지 않는다면, defaultDataSource를 사용한다.

 

# 구현 단계

 

○ context-datasource.xml

dataSource가 Master와 Replica1로 나누어져 있고 디폴트는 dataSourceMaster로 설정되어 있는걸 확인할 수 있다.

   ....
<bean id="dataSource" class="website.fedulov.routing.RoutingDataSource">  
 <property name="targetDataSources">
   <map key-type="com.sabienzia.routing.DbType">
     <entry key="MASTER" value-ref="dataSourceMaster"/>
     <entry key="REPLICA1" value-ref="dataSourceReplica"/>
   </map>
 </property>
 <property name="defaultTargetDataSource" ref="dataSourceMaster"/>
</bean>

<bean id="dataSourceMaster" class="org.apache.commons.dbcp.BasicDataSource">  
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="${db.master.url}"/>
  <property name="username" value="${db.username}"/>
  <property name="password" value="${db.password}"/>
</bean>  
<bean id="dataSourceReplica" class="org.apache.commons.dbcp.BasicDataSource">  
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="${db.replica.url}"/>
  <property name="username" value="${db.username}"/>
  <property name="password" value="${db.password}"/>
</bean>  

 

○ RoutingDataSource

determineCurrentLookupKey() 메소드를 재정의

package website.fedulov.routing.RoutingDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class RoutingDataSource extends AbstractRoutingDataSource {  
    @Override
    protected Object determineCurrentLookupKey() {
        return DbContextHolder.getDbType();
    }
}

 

public enum DbType {  
   MASTER,
   REPLICA1,
}

public class DbContextHolder {

   private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<DbType>();

   public static void setDbType(DbType dbType) {
       if(dbType == null){
           throw new NullPointerException();
       }
      contextHolder.set(dbType);
   }

   public static DbType getDbType() {
      return (DbType) contextHolder.get();
   }

   public static void clearDbType() {
      contextHolder.remove();
   }
}

 

추가로 LazyConnectionDataSourceProxy를 사용하면 실제로 커넥션이 필요한 경우에만 커넥션을 점유하게 된다.

 

반응형

'Server' 카테고리의 다른 글

Apache ssl.conf 설정하기  (0) 2023.06.16
Apache httpd.conf 설정하기  (0) 2023.06.12
우분투의 명령어  (0) 2022.08.20
http, https 기본 포트 번호  (0) 2022.08.17
VirtualBox 서버 설정  (0) 2022.08.04

+ Recent posts