-
[JAVA] Scheduler 와 shedlock 이야기IT개발이야기 2023. 1. 11. 13:47728x90반응형SMALL
현재 프로젝트에서 어플리케이션이 여러개가 도는 상황 속에 스케줄러를 통해 시간대별 메일을 발송을 중복없이 해야하는 상황이 생겼습니다.
DB는 하나이며, 어플리케이션은 여러개 도는 환경이고, 메일이 다중으로 보내지는걸 막으려고 합니다.
그래서 일단 Shedlock 을 적용하여, 실험을 해 보았습니다.
123456789CREATE TABLE shedlock (name VARCHAR(64),lock_until TIMESTAMP(3) NULL,locked_at TIMESTAMP(3) NULL,locked_by VARCHAR(255),PRIMARY KEY (name))cs 12345678910<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>cs 12345678@SpringBootApplication@EnableScheduling@EnableSchedulerLock(defaultLockAtLeastFor = "PT10S",defaultLockAtMostFor = "PT15S")public class SchedulergApplication {public static void main(String[] args) {SpringApplication.run(SchedulergApplication.class, args);}}cs 1234567spring:datasource:#mssqldriverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriverurl: jdbc:sqlserver://ip;databaseName=name;currentSchema=schemausername: idpassword: pwcs 123456789101112131415161718@Configurationpublic class SchedulerConfiguration {private final int POOL_SIZE = 7;// shedlock jdbc 설정@Beanpublic LockProvider lockProvider(DataSource dataSource) {return new JdbcTemplateLockProvider(dataSource);}// threadPoll 설정@Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();threadPoolTaskScheduler.setPoolSize(POOL_SIZE);threadPoolTaskScheduler.setThreadNamePrefix("scheduled-task-pool");threadPoolTaskScheduler.initialize();scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);}}cs 12345678910@Slf4j@Componentpublic class Scheduler {// test@Scheduled(cron = "0 0 7 * * *")@SchedulerLock(name = "testSpringSchedule")public void scheduler1() throws Exception {// mail 발송log.info("mail발송");}cs defaultLockAtMostFor 는 해당 스케줄러가 도는 동안 다른 스케줄러가 대기하는 시간이며,
defaultLockAtLeastFor 는 해당 스케줄러가 시작되고 난 후 기다리는 시간이다.
-> 완료 된 뒤 중복 실행 방지를 하는데 추가잠금을 해주는 LeastFor이 핵심이다.
-> LeastFor < MostFor 관계를 유지해야 에러가 안난다.
이후 시간대 별 메일이 잘 오는 것을 확인하였습니다.
(현 소스는 실제 메일이 보내는 소스는 생략하였으며, 메일 보내기는 https://donepick92.tistory.com/14 참고해주세요.)
하지만, 실제 여러개의 어플리케이션에서 호출하는 로그를 본 결과, 0.01초 차이로 동시에 호출 시 에는 여러개의 메일이 오는 단점을 확인하였습니다.
( 스케줄러가 실행 된 후 DB에 접근하기 하기도 전에 다른 어플리케이션에서 0.01초 차이로 스케줄러가 중복으로 실행됨을 서버 로그를 통해 확인하였습니다.
shedlock은 실제 적용해 본 결과 여러개의 어플리케이션을 동시에 서비스가 돌때는 적절한 방법이 아니라고 저는 판단됩니다.
만약 조금 더 개선할 기회가 생긴다면 이론적으로 명확한 Zookeeper 라는 분산코디네이션을 공부하여 직접 운영서버에 반영해 보고 싶습니다.
728x90반응형LIST'IT개발이야기' 카테고리의 다른 글
[SPRINGBOOT] Thymeleaf 에 대해서 (개념, 활용팁) (0) 2023.01.13 [JAVA] javax.mail 를 통한 Email 보내기 (0) 2023.01.12 [VUE] .vue 많이 쓰는 component 모음 (0) 2023.01.10 [VUE] SCRIPT 구성 (0) 2023.01.10 [Angular] 기초 개념 정리 (0) 2023.01.08