[ 목차 ]
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
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
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
'Spring' 카테고리의 다른 글
springBoot-H2database연동하기 (0) | 2021.12.26 |
---|---|
SpringBoot-외장Tomcat으로 배포하기 (0) | 2021.12.24 |
SpringMVC-프로젝트 생성 (intellij) (0) | 2021.12.05 |
SpringBoot-@Scheduled설정방법 (0) | 2021.11.05 |
SpringBoot-@PathVariable에 특수문자 허용 (1) | 2021.10.08 |