From 0267fd563dc182ae559756db728120850066132c Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 19 Sep 2023 23:28:31 +0900 Subject: [PATCH] =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=A1=9C=EA=B9=85=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\210\354\231\270 \354\262\230\353\246\254.mdx" | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git "a/blog/2023-3/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254.mdx" "b/blog/2023-3/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254.mdx" index 0c059268c..310be8769 100644 --- "a/blog/2023-3/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254.mdx" +++ "b/blog/2023-3/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254/2023-09-18-\353\271\204\353\217\231\352\270\260 \354\230\210\354\231\270 \354\262\230\353\246\254.mdx" @@ -11,7 +11,11 @@ tags: [async, exception] ### 비동기 예외 발생시 로깅 설정 -Spring에서 지원해 주는 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 처리하는 클래스를 생성했다. +스프링 4.1 부터 제공되는 [AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다. + +따라서 AsyncUncaughtExceptionHandler 구현해서 예외를 핸들링하는 클래스를 생성했다. +기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다. +비동기 예외 처리의 경우에도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다. ```java title=AsyncExceptionHandler @Slf4j @@ -41,15 +45,15 @@ public class AsyncConfig implements AsyncConfigurer { } ``` -이제 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아서 처리를 해준다. +이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아서 처리를 해준다. ### MDC 정보 연동 문제 -트립드로우의 애플리케이션은 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다. 비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없었다. +비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없었다. ![./mdc-null.png](./mdc-null.png) -Spring 4.3 이상부터 제공되는 [TaskDecorator](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html)를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다. +스프링 4.3 이상부터 제공되는 [TaskDecorator](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html)를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다. ```java title=MdcTaskDecorator public class MdcTaskDecorator implements TaskDecorator { @@ -106,4 +110,5 @@ public class AsyncConfig implements AsyncConfigurer { [spring async, baeldung](https://www.baeldung.com/spring-async) [@Async will not call by @ControllerAdvice for global exception](https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception) [Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니](https://blog.gangnamunni.com/post/mdc-context-task-decorator/) -[TaskDecorator, Spring docs](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html) \ No newline at end of file +[TaskDecorator, Spring docs](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html) +[AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html) \ No newline at end of file