여러 인스턴스의 스케줄러 동기화 기능을 제공
쉽게 말해서 scal-out 을 하여 여러대의 was가 생성될 경우
was가 한대일때는 스케줄러가 한번만 실행되지만 was가 여러개로 늘어날 경우 해당 스케줄러가 was의 갯수만큼 실행됨
ShedLock은 Spring Boot 기반의 분산 락 라이브러리로, 여러 서버에서 동시에 실행되는 작업들 간에 충돌을 방지하고 작업 실행의 독점성을 보장해줍니다.
Quartz, Cron 또는 FixedRate와 같은 스케줄링 프레임워크와 함께 사용될 수 있습니다.
데이터베이스를 사용하여 락을 관리합니다. 예를 들어, 데이터베이스 테이블에 특정 락 정보를 저장하고, 작업을 수행할 때 해당 락 정보를 확인하여 락이 획득되었을 경우에만 작업을 실행하고, 락이 획득되지 않았을 경우에는 다음 스케줄링 시간으로 넘어갑니다.
Spring Boot와 함께 사용되기 때문에, ShedLock은 Spring의 기능을 쉽게 활용할 수 있습니다. 예를 들어, ShedLock은 Spring의 AOP를 사용하여 간단한 애너테이션을 사용하여 락을 적용할 수 있습니다.
ShedLock은 분산 환경에서 안전하고 신뢰성 높은 작업 수행을 보장해주는 좋은 라이브러리입니다.
해당 라이브러리는 데이터베이스가 있어야 사용가능함
SpringBoot와 연결한 데이터베이스에 테이블을 생성
=================================================================================================================
CREATE TABLE shedlock (
name VARCHAR(64),
lock_until TIMESTAMP(3) NULL,
locked_at TIMESTAMP(3) NULL,
locked_by VARCHAR(255),
PRIMARY KEY (name)
)
=================================================================================================================
build.gradle 파일에 아래의 내용을 추가
=================================================================================================================
implementation 'net.javacrumbs.shedlock:shedlock-spring:4.14.0'
implementation 'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:4.14.0'
//DB커넥션을 위해 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.27'
=================================================================================================================
application.yml 파일에 아래의 내용을 추가
=================================================================================================================
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/if_buy?serverTimezone=UTC&characterEncoding=UTF-8
username: securus
password: securus1234
server :
port : 9997
=================================================================================================================
=================================================================================================================
@EnableScheduling
@SpringBootApplication //추가
public class ShedlockTestApplication {
public static void main(String[] args) {
SpringApplication.run(ShedlockTestApplication.class, args);
}
}
=================================================================================================================
=================================================================================================================
package com.sungchul.shedlocktest.config;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class SchedulerConfiguration {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withJdbcTemplate(new JdbcTemplate(dataSource))
.usingDbTime()//DB시간사용
.build()
);
}
}
=================================================================================================================
@SchedulerLock에 있는 name 은 DB테이블에 들어갈 이름으로, 여러개의 스케줄러를 설정할 경우 각각 이름을 다르게 하면됨
=================================================================================================================
package com.sungchul.shedlocktest.schdule;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@EnableSchedulerLock(defaultLockAtMostFor = "PT10S")
@Component
public class ScheduleTest {
@Scheduled(cron ="0 0/1 * * * *")
@SchedulerLock(name="ScheduleTestMethod",lockAtMostFor = "10S", lockAtLeastFor = "10S")
public void ScheduleTestMethod(){
for(int i=0;i<100000;i++){
System.out.println("#### i : " + i);
}
}
}
=================================================================================================================
1. 테스트를 위해 gradle 에서 bootjar 더블클릭
2. jar파일이 생성되면 port 번호를 변경후 gredle clean 후 다시 bootjar 더블클릭
3. 위 방법을 3번 한후 CMD창을 3개 띄운후 각각 jar 파일 실행
java -jar shedlockTest-1.jar
java -jar shedlockTest-2.jar
java -jar shedlockTest-3.jar