본문 바로가기
공부/프로그래밍

[SPRING] 멀티서버 스케쥴 처리를 위한 LOCK API: ShedLock

by demonic_ 2017. 11. 30.
반응형

멀티서버에서 스케쥴을 중복되게 처리하지 않으려면 LOCK 정보를 공통으로 참조하는 곳에서 관리되어야 한다. 관리될 곳으로는 DB가 가장 적당하다.


관련 멀티 서버에 대한 스케쥴 처리를 위해 다음의 API를 사용했다.

아래의 API를 사용하기 위해서는 Java 8 이상의 버전이 필요하다 그 외 의존적인 API 가 아래와 같이 필요하다.


// 코드가 있는 GifHub

ShedLock: https://github.com/lukas-krecan/ShedLock


// 필수

- Java 8

- Spring Framework

- slf4j-api



어노테이션을 이용하여 Lock을 걸 수 있으며 Mysql 에다가 걸어두는 것으로 사용했다.

(mongoDB, Redis, zookeeper 를 이용할 수도 있다.)



- pom.xml  을 통해 다운로드.

<!-- 공통 -->

<dependency>

    <groupId>net.javacrumbs.shedlock</groupId>

    <artifactId>shedlock-spring</artifactId>

    <version>0.16.0</version>

</dependency>

<!-- JDBC TEMPLATE -->

<dependency>

    <groupId>net.javacrumbs.shedlock</groupId>

    <artifactId>shedlock-provider-jdbc-template</artifactId>

    <version>0.16.0</version>

</dependency>



- Spring 설정

<!--

 Spring 에 설정 

DB 접속정보를 전할 dataSource 를 설정 => dataSourceMySQL

-->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSourceMySQL" />

<property name="configLocation" value="/WEB-INF/spring/mybatis-config.xml" />

<property name="mapperLocations">

<array>

<value>/WEB-INF/classes/mapper/*.xml</value>

</array>

</property>

</bean>



<!--

위에서 설정한 dataSourceMySQL(dataSource) 를 아래 ref 에 추가

-->

<!-- lock provider of your choice (jdbc/zookeeper/mongo/whatever) -->

<bean id="lockProvider" class="net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider">

    <constructor-arg ref="dataSource"/>

</bean>


<!-- Your task(s) without change (or annotated with @Scheduled)-->

<bean id="scheduler" class="net.javacrumbs.shedlock.spring.SpringLockableTaskSchedulerFactoryBean">

    <constructor-arg>

        <task:scheduler id="sch" pool-size="10"/>

    </constructor-arg>

    <constructor-arg ref="lockProvider"/>

    <constructor-arg name="defaultLockAtMostFor">

        <bean class="java.time.Duration" factory-method="ofMinutes">

            <constructor-arg value="10"/>

        </bean>

    </constructor-arg>

</bean>



- JDBC로 한 경우 테이블 생성.

CREATE  TABLE  shedlock (

    name VARCHAR ( 64 ),

    lock_until TIMESTAMP ( 3 ) NULL ,

    locked_at TIMESTAMP ( 3 ) NULL ,

    locked_by   VARCHAR ( 255 ), 

     PRIMARY KEY (name)



- 사용법

@Scheduled(cron = "0 0 9 * * ?")        // 크론탭의 설정.

@SchedulerLock(name = "test" // 고유키 값 설정

, lockAtLeastFor = 60 * 1000 /* 잠금을 유지해야하는 기간을 지정하는 속성(초단위) */

, lockAtMostFor = 10 * 60 * 1000 /* 잠금을 유지해야하는 최소 시간을 지정하는 속성(초단위) */)

public void testScheduler() {

System.out.println("테스트...");

}



잠금중인지 확인하는 방법은 위에서 생성한 shedlock 테이블을 조회해보면 된다.

실행중이라면 name 쪽에 고유키 값이 동일한 row가 보이고 종료되고 나면 name에 지정한 고유키 값이 사라진다. 조회되지 않는다면 현재 실행중이 아닌 것이다.



반응형

댓글