일상IT
[Spring] Blue-Green 환경에서의 Scheduler 본문
Blue-Green 배포란?
- 똑같은 서버 환경을 Blue, Green 2개 준비하고 최신버전을 한쪽에 배포하여 nginx같은 웹서버를 통해서 최신버전이 배포된 서버로 스위칭하는 배포 기법
Blue-Green 환경에서 Spring Scheduler 문제점
- 보통 Spring 애플리케이션에서 스케줄러를 돌리는 방식은 Spring Scheduler를 쓰는 방식과 Jenkins 같은 도구를 활용하여 애플리케이션의 특정 API를 특정 주기로 호출하는 식으로 구현할 수 있다.
- 문제는 Spring Schduler를 사용할 때 발생한다. Spring Scheduler를 사용할 경우 멀티 인스턴스 환경에서 중복으로 실행될 수 있기 때문에 ShedLock같은 라이브러리를 활용해 하나의 인스턴스에서만 스케줄이 실행되도록한다.
- 이런 경우 새로운 버전에서 스케줄러 로직 관련 수정이 있었을 경우 구버전 인스턴스가 살아있으면 해당 인스턴스가 스케줄 락을 잡아가면서 실행시킬 수 있다. 운영환경에서 구버전 스케줄 로직이 돌아버리면서 장애가 발생할 수 있는 엣지 케이스가 존재한다.
해결방법
- 외부(Jenkins 같은 시스템)에서 스케줄을 돌려서 API 호출하는 방법
- 단점은 히스토리를 모르는 사람이 어플리케이션 소스만 보았을 때 API만 존재할 것이고 주석을 남겨놓지 않는 이상 해당 API가 외부 스케줄러에 의해서 호출되는 것인지 알 수 없다.
- 외부 시스템이 죽었을때 스케줄 로직이 안돌아갈 수 있다.
- 최신버전 배포 후 구버전 인스턴스를 종료시키는 방법
- 단점은 블루, 그린 스왑 후 구버전에 들어왔던 트래픽이 끊기는 것을 확인 후 종료시켜야 되기 때문에 종료시키는데 시간이 걸릴 수 있다. 인스턴스가 종료되기 전에 구버전 인스턴스에서 스케줄이 돌아버린다면 에러가 발생할 수 있다.
- 새로운 버전에서 에러 발생으로 구버전 롤백이 필요할 때 인스턴스가 이미 종료되어 있다면 살려서 다시 스왑하는 시간이 걸린다.
- 액티브인지 스탠바이인지를 애플리케이션에서 알 수 있게 하여 스케줄러 실행을 제어하는 방법
- 인스턴스 내의 특정 파일이든, 다른 저장소든, 로드 밸런서에서 액티브 인스턴스에만 호출하는 헬스체크 API를 캐치하든, 서버 애플리케이션이 액티브/스탠바이라는 것을 알 수 있도록 하여 액티브일 때만 스케줄러를 실행하도록 한다.
- 내가 해당 인프라를 구성할 수 있는 권한이 있다면 가능하겠지만 보통 큰 회사는 인프라, 서버 인스턴스를 전문적으로 관리하는 팀들이 따로 있기에 구성할 수 있는 환경이 안된다면 힘든 방법이다.
결론
- 환경만 구성된다면 3번같은 경우가 소스에 간단한 주석 정도로 히스토리를 알 수 있고 안전한 방법으로 보인다.
- 현실적으로는 Jenkins 같은 시스템들이 죽는 것을 가정하게 되면 끝이 없어지니 1번이 제일 쉽고 간편한 방법이라고 생각된다.