서버 한대 띄우면 상관없는데
여러대 띄우면
스케줄러코드가 동시에 작동한다..!
profile 로 해결하기
음 active profile -cron 해준 노드가 장애낫을 때
다른노드가 작동함에도 불구하고 스케줄링 작업이 일어나지 않음 ..!
zookeeper 사용하는 환경이엿다면
distributed locking system을 만들 수 잇다는데
현재 서비스에서 이거 사용안하니깐 일단 패스..
spring-based solution 이랜다 이거를 사용해보자
최신버전 shedlock 불러오고
테이블 생성해주자!
provider 설정 및 등록 해주고
@Log4j2
@Configuration
@RequestArgsConstructor
public class DatabaseConfig
{
private final DataSourceProperty dataSourceProperty;
private DataSource createDataSource(dataSourceProperty.Base dataSourceProperty, String dbUser, String dbPassword)
{
HikariDataSource hikariDataSource = (HikariDataSource) DataSourceBuilder.create()
.driverClassName(dataSourceProperty.getDriverClassName())
.url(dataSourceProperty.getJdbcUrl())
.username(dbUser)
.password(dbPassword)
.build();
log.info(String.format("DB Setting // username: %s", dbUser));
hikariDataSource.setMaximumPoolSize(dataSourceProperty.getMaximumPoolSize());
return hikariDataSource;
}
// ..중략
//Schedlock config
@Bean
public LockProvider lockProvider()
{
DataSource masterDataSource = createDataSource(dataSourceProperty.getMaster(),
dataSourceProperty.getMaster().getUsername(),
dataSourceProperty.getMaster().getPassword());
return new JdbcTemplateLockProvider(masterDataSource);
}
}
@EnableSchedulerLock 도 추가
@SpringBootApplication
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class CampusnowApiApplication {
public static void main(String[] args) {
SpringApplication.run(CampusnowApiApplication.class, args);
}
}
사용법은
스케줄 걸려잇는 메소드 위에 @ShedLock 달아주면 된다.
속성으로는
name : 작업의 고유 이름, shedlock 테이블의 name 칼럼으로 기본키 역할을 하게 된다.
lockAtLeastFor: 작업이 lock 되어야 할 최소한의 시간
lockAtMostFor : 작업 lock 되는 최대 시간(실행 노드가 죽엇을 때 방지)
권장되는 LOCK 시간은 실행주기 에서 -1 분 이라고 한다.
https://faun.pub/spring-scheduler-in-multi-node-environment-49814e031e7c