Yeji's Tech Notes
article thumbnail
Published 2021. 11. 17. 15:48
SpringBoot-@ShedLock 설정 방법 Spring
반응형

[ 목차 ]

1. dependency 추가

2. liquibase shedlock 추가

3. LockProvider 설정

4. @EnableSchedulerLock

5. Task 생성

 

Spring에서는 Scheduling jobs들을 위한 쉬운 API를 제공합니다.

기본적으로 Spring은 여러 인스턴스에 대한 스케줄러 동기화를 처리할 수 없습니다.  대신 모든 노드에서 동시에 작업을 실행합니다.

Shedlock을 사용하면 예약된 작업이 동시에 한번만 실행하게 됩니다. 

(Shedlock은 Quartz의 대안으로 사용되는 java lib)

 

Dependency추가

// shedLock for gradle
compile("net.javacrumbs.shedlock:shedlock-spring:2.2.0")
compile("net.javacrumbs.shedlock:shedlock-provider-jdbc-template:2.1.0")

// shedLock for maven
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>2.1.0</version>
</dependency>

spring과 함께 shedloock을 사용하기 위해선 shedlock-spring dependecy를 추가해줍니다.

https://search.maven.org/search?q=g:net.javacrumbs.shedlock%20AND%20a:shedlock-spring&core=gav 

 

Maven Central Repository Search

 

search.maven.org

 

 

 liquibase에 shedlock table추가

<createTable tableName="shedlock">
	<column name="name" type="varchar(64)">
    	<constraints nullable="false"/>
    </column>
    <column name="locked_by" type="varchar(64)">
    	<constraints nullable="false"/>
    </column>
    <column name="locked_at" type="DATETIME" defaultValueComputed="CURRENT_TIMESTAMP">
    	<constraints nullable="false"/>
    </column>
    <column name="lock_until" type="DATETIME">
    	<constraints nullable="false"/>
    </column>
</createTable>

scheduler lock들의 정보를 저장하기 위한 ShedLock DB table을 생성해야 합니다.

// Caused by: org.postgresql.util.PSQLException: ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification

<addUniqueConstraint columnNames="name" constraintName="uk_shedlock_name" tableName="shedlock"/>

document보고 실행했을때, 위와같은 에러가 발생해서 Unique제약조건을 추가해줬습니다.

 

LockProvider 

@Configuration
public class SchedulerConfiguration{
	
    @Bean
    public LockProvider lockProvider(DataSource dataSource){
    	return new JdbcTemplateLockProvider(dataSource);
    }
}

위의 구성으로 LockProvider를 구성해보겠습니다.

 

@EnableSchedulerLock 추가

@SpringBootApplication
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringApplication.class, args);
    }
}

defaultLockAtMostFor매개변수는 실행노드가 죽을경우 잠금을 유지해야하는 기본시간을 지정합니다.

ISO8601 Duration format을 사용합니다.

 

https://en.wikipedia.org/wiki/ISO_8601#Durations

 

ISO 8601 - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search International standards for representing dates and times Current date and time expressed according to ISO 8601 [refresh]Date2021-11-12Date and time in UTC2021-11-12T00:12:29+00:002021-

en.wikipedia.org

 

Task생성

@Component
class TaskScheduler {

    @Scheduled(cron = "0 0/15 * * * ?")
    @SchedulerLock(name = "TaskScheduler_scheduledTask", 
      lockAtLeastForString = "PT5M", lockAtMostForString = "PT14M")
    public void scheduledTask() {
        // ...
    }
}

Scheduled task를 다루기 위해 Shedlock을 추가했습니다. 간단하게, @Scheduled와 @SchedulerLock annotation을 추가하면 됩니다.

 

첫번째로, @Scheduled는 cron format을 사용합니다. 위의예시는 "매일 15분마다" 동작하는 cron표현식입니다.

다음으로, @SchedulerLock에서 name parameter는 unique해야합니다.

name => className_methodName을 따릅니다. 우리는 동시에 두번이상 실행되는 것을 원하지않으면 shedlock은 이를 위해 unique한 이름을 사용합니다.

 

name을 제외한 Optional paramters을 추가했습니다.

 

lockAtLeastForString

: 메서드 호출 사이에 거리를 둘 수 있도록 추가했습니다. "PT5M"은 5분동안 method가 lock될 것이라는 의미입니다.

lockAtMostForString

: 실행노드가 죽을 경우 잠금을 유지해야하는 기간을 지정해주는 paramter입니다. "PT14M"을 사용하면 14분 이상 lock되지 않습니다.

 

 

 

 

 

https://docs.liquibase.com/concepts/advanced/preconditions.html

 

preconditions | Liquibase Docs

<databasechangelog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xsi:schemalocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibas

docs.liquibase.com

 

반응형
profile

Yeji's Tech Notes

@Jop

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!