개발놀이터

Graceful Shutdown (feat. Hard Shutdown) 본문

배포/CI , CD

Graceful Shutdown (feat. Hard Shutdown)

마늘냄새폴폴 2023. 7. 7. 19:36

여러분들이 배포를 진행하는데 어떤 배포 방법을 사용하는지에 따라 다르겠지만 기존 배포했던 서버를 내려야 하는 상황이 생길 것입니다. 

 

만약 블루그린 배포를 진행했다고 가정하면 새로 올릴 서버를 띄운 다음 기존 서버를 죽여야하는 상황이 생기겠죠? 그 때 그냥 서버를 죽여버리면 사용자는 굉장히 난처한 상황에 놓일 것입니다. 

 

혹시라도 그 사용자가 결제를 진행하고 있다가 서버가 내려가서 결제가 취소된다면 부정적인 사용자 경험으로 이어질 수 있습니다. 

 

하지만 그런 상황이라면 조금 기분 나쁘고 말겠지만 결제가 진행되고 있는 도중 (API에 요청을 보내서 처리하고 있던 도중) 서버가 내려가버리면 이건 예외상황에 의해 트랜잭션이 롤백되는 것이 아니기 때문에 개발자 입장에서도 처리하기 난처한 상황입니다. 

 

그렇기 때문에 Graceful Shutdown 우리말로 우아한 종료를 진행해야 합니다. 이제 Graceful Shutdown이 어떤 것인지 한번 알아보도록 하죠. 

 

Graceful Shutdown

Graceful Shutdown은 아주 간단한 개념입니다. 쉽게 설명하자면 천천히 종료하는 것 입니다. 구현하는 것도 정말 간단합니다. 스프링부트에 내장되어 있는 웹 서버들 (e.g Tomcat) 이 Graceful 을 지원하고 있기 때문이죠. 

 

이 Graceful Shutdown이 작동하는지 직접 눈으로 확인해보도록 하겠습니다. 

 

@RestController
@Slf4j
public class TestController {

    @GetMapping("/log/test/{id}")
    public String test(@PathVariable("id") Long id) throws InterruptedException {
        log.info("Process Start " + id);
        Thread.sleep(20000);
        log.info("Process End " + id);
        return "ok";
    }
}

테스트를 위해 컨트롤러를 만들고 프로세스가 시작되고 20초뒤에 종료되는 로직을 준비해봤습니다. 

 

정상적으로 종료가 된다면 마지막 Process End 로그가 찍히겠죠? 

 

저는 Graceful 을 테스트하기 위해 테스트 API에 GET 요청을 보내자마자 kill 명령어를 통해 해당 포트를 죽일것입니다. 그 때 Graceful 이 적용되기 전과 후를 비교해보겠습니다. 

 

우선 로그가 잘 찍히는지 확인해봐야겠습니다. 서버를 띄우고 해당 API로 요청을 보내보겠습니다. 

 

 

정상적으로 잘 작동합니다. 

 

이제 요청을 보내자마자 kill 명령어를 통해 8080포트를 죽이겠습니다. 

 

 

시작 로그만 찍히고 종료 로그가 찍히지 않았습니다. 

 

자 이제 Graceful 을 구현해봅시다. 

 

Spring Boot 에서 Graceful Shutdown

스프링 부트에서는 정말 간단하게 설정 하나만으로 Graceful을 구현할 수 있습니다. 

 

먼저 application.yml 파일에

 

이렇게 적어주면 끝입니다. 

 

자 이제 다시 시작해서 똑같이 요청을 보내고 kill로 죽여보겠습니다. 

 

 

오오... Graceful Shutdown이 적용됐습니다. 

 

※주의!

이 작업을 윈도우 환경에서 실행하면 원하는 결과가 나오지 않습니다!

 

윈도우에서 만약 8080포트를 죽이려고 한다면 강제종료하는 수밖에 없기 때문에 무슨 수를 써도 시작 로그만 찍히고 강제종료 해버립니다. 

 

때문에 리눅스 환경에서 kill -15 {pid} 명령어를 통해 작업을 종료해야 원하는 결과를 얻을 수 있습니다. 

 

 

마치며

블루 그린 배포를 진행했을 때 주의해야 하는 점을 공부하면서 Graceful Shutdown을 구현해야 한다는 얘기를 듣고 조금 겁먹었지만 생각보다 아무것도 아니라 조금 당황했습니다. 

 

하지만 간단하다고 중요하지 않은 건 아니죠. Graceful Shutdown은 정말 중요한 옵션이니 배포를 진행했다면 반드시 진행해야 할 것입니다. 

 

긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요~

 

 

출처

https://bravenamme.github.io/2020/10/06/graceful-shutdown/

 

Spring boot Graceful Shutdown

시작하며 보통 애플리케이션에서 변경 사항이 있으면, 애플리케이션을 재시작 해야 변경사항이 반영된다. 물론 배포 방식에 따라 Blue-Green 배포 형식을 따르게 되면, 이전 버전 앱을 굳이 죽일

bravenamme.github.io