Spring Boot server.shutdown graceful 옵션

안녕하세요. 

 

오늘은 Spring Boot 서버가 종료될 경우

 

클라이언트의 요청에 대해서 응답받지 못한 이슈에 대해 공유하고자 합니다.

 

클라이언트는 별도의 spring boot 서버였고 서버A라 지칭하겠습니다. 네트워크 타임아웃에 대해서 30초의 간략한 시간으로 설정해두었습니다.

 

서버는 마찬가지로 별도의 spring boot 서버였고 서버B라 지칭하겠습니다. 서버A에 의해 다수의 요청을 받는 환경에서 서버B를 종료했을 경우, 

 

서버A에서 네트워크 타임아웃이 발생하였습니다.

 

그 이유는 바로 서버B의 종료가 급격하게 이루어짐으로써 몇개의 요청에 대한 응답이 유실되었기 때문인데요. 이것은 서버의 종료(shutdonw) 속성이 IMMEDIATE 으로 되어있었기 때문입니다.

 

해당 속성은 서버가 종료될 때, 들어온 요청에 대해서는 상관없이 바로 종료한다는 속성입니다.

 

그렇다면 해당 이슈를 해결하기 위해서는 어떻게 해야할까요??

 


 

결국 서버B의 종료에 의해 서버A(클라이언트 서버)는 응답을 받지 못한채 타임아웃 처리되어버리고 말았습니다. 서버A의 스레드는 해당 타임아웃 만큼의 스레드 N개에 대한 손실을 볼 수밖에 없습니다.(비동기 클라이언트가 아니라면..)

 

그래서 GRACEFUL 속성을 사용할 수 있습니다.

 

해당 속성은 서버 종료시 새로운 요청에 대해서는 수신하지 않고 기존 요청에 대해서는 완전히 처리를 진행하고 서버종료를 마무리하는 것을 말합니다.

 

결국 신규 요청은 받지 않은 채로 기존 요청은 마무리하므로써 요청에 대한 응답의 유실은 최소한 피할 수 있게 됩니다.

 

또한 타임아웃도 추가할 수 있습니다. (graceful 하게 기존 요청을 처리할 수 있도록 시간을 유예하는 것)

 

lifecycle.timeout-per-shutdown-phase = 10s

 

해당 속성을 활용하면 예컨데 100개의 요청이 남아있는 상태에서 10초 동안 해당 요청을 모두 처리하고서 서버를 종료하게 됩니다.

 

따라서 100개의 요청이 11초가 걸리는 환경이라면 1초동안에 처리할 수 있는 갯수의 요청에 대해서는 클라이언트 서버가 응답을 받지 못하므로 해당 속성값에 대한 seconds 값은 적절하게 조절해야 할 것 같습니다.

 

application.properties를 활용

 

server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=20s

 

application.yml을 활용

server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 20s

 


 

해당 설정에 대한 enum으로 spring.boot.web.server 패키지에 정의되어있습니다. ( 해당 설정은 spring boot 2.3 이상에서 가능합니다. )

public enum Shutdown {

   /**
    * The {@link WebServer} should support graceful shutdown, allowing active requests
    * time to complete.
    */
   GRACEFUL,

   /**
    * The {@link WebServer} should shut down immediately.
    */
   IMMEDIATE;

}

 

 

 

댓글

Designed by JB FACTORY