포스트

2022-11-22-TIL

2022-11-22-TIL

Today I Learned

Graceful Shutdown

Graceful shutdown은 애플리케이션을 끌 때 새 요청은 더 받지 않고, 이미 처리 중인 요청은 끝까지 마친 뒤 종료하는 방식이다. 배포할 때마다 서버를 내렸다 올리는데, 그 순간 처리 중이던 요청이 끊기면 사용자는 에러를 보게 된다.

Spring Boot는 server.shutdown=graceful 설정 하나로 이 동작을 켠다. Jetty, Reactor Netty, Tomcat, Undertow 네 가지 내장 웹 서버와 서블릿, 리액티브 애플리케이션 모두에서 지원한다. 종료는 애플리케이션 컨텍스트를 닫는 과정에서 SmartLifecycle 빈을 멈추는 가장 이른 단계에 일어나고, 유예 시간 동안 기존 요청은 마칠 수 있지만 새 요청은 허용되지 않는다. 새 요청을 막는 방식은 서버마다 다르다. Jetty, Reactor Netty, Tomcat은 네트워크 수준에서 요청을 받지 않고, Undertow는 요청을 받되 바로 503을 돌려준다(Spring Boot: Graceful Shutdown).

1
2
3
4
5
server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 20s

유예 시간은 spring.lifecycle.timeout-per-shutdown-phase로 정한다. 문서는 IDE가 제대로 된 SIGTERM을 보내지 않으면 graceful shutdown이 동작하지 않을 수 있다고도 적는다. 컨테이너 환경에서는 오케스트레이터가 SIGTERM을 보낸 뒤 강제 종료하기까지의 시간이 이 유예 시간보다 길어야 의미가 있다.


저작권

음원의 저작권과 저작인접권은 지난 TIL에서 정리했다. 작사가와 작곡가의 저작권, 그리고 실연자, 음반제작자, 방송사업자의 저작인접권이 한 곡에 함께 걸려 있다는 점이 핵심이다.


@Async

Spring의 @Async를 메서드에 붙이면 호출한 쪽은 즉시 반환되고, 실제 실행은 Spring TaskExecutor에 제출된 작업에서 따로 일어난다. 반환 타입은 void이거나 Future 계열(Future, ListenableFuture, CompletableFuture)이어야 한다(Spring Framework: The @Async annotation).

쓰면서 주의할 점이 세 가지 있다.

  • 예외 처리: Future를 반환하면 get()을 호출할 때 예외가 다시 던져진다. void 메서드에서 난 예외는 호출한 쪽으로 전달되지 않고, 기본적으로 로그만 남는다. 따로 처리하려면 AsyncUncaughtExceptionHandler를 등록해야 한다. 호출은 이미 반환된 뒤이므로 호출부를 try-catch로 감싸도 비동기로 실행되는 메서드 안의 예외는 잡히지 않는다.
  • 자기 호출: @Async는 프록시로 동작한다. 같은 클래스 안에서 this.asyncMethod()처럼 부르면 프록시를 거치지 않으므로 비동기로 실행되지 않는다(Spring AOP: Understanding AOP Proxies). 비동기 메서드는 다른 빈에 두고 주입받아 호출해야 한다.
  • 라이프사이클 콜백: @PostConstruct 같은 초기화 콜백과 함께 쓸 수 없다.
1
2
3
4
@Async
public CompletableFuture<Result> fetch(long id) {
    return CompletableFuture.completedFuture(client.get(id));
}
  • https://www.digitalocean.com/community/tutorials/spring-async-annotation
  • https://www.baeldung.com/spring-async
  • https://stackoverflow.com/questions/38306115/call-for-asynchronous-method-in-try-catch-finally-block
  • http://dveamer.github.io/java/SpringAsync.html
  • https://www.javadevjournal.com/spring-boot/spring-async-annotation/
참고한 자료외부 출처 3

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다