비동기(Async) 처리 관련 학습 내용을 간단히 정리해보려고 합니다.
이번에 프로젝트를 진행하면서 ‘동시에 여러 작업을 처리하는 방법’에 대해 내실을 다지는 계기가 되었습니다.
1. 왜 비동기 처리가 중요할까?
처음엔 “스프링 부트로 API 만들어서 RestController에 @GetMapping/@PostMapping 달아놓으면 끝”이라고만 생각했는데 막상 유저 수가 많아지고, 한 번에 요청이 빗발치면 서비스 응답이 늦어질 뿐 아니라 서버 자원도 효율적으로 쓰지 못하는 경우가 생겼습니다.
- 동시성: 여러 요청을 동시에 처리해야 하는 상황
- 자원 효율성: 쓰레드를 최소한으로 쓰면서 최대 성능 뽑아내기
이 두 가지가 중요하다는 걸 깨닫고, 스프링에서 제공하는 비동기 처리 기법을 알아보기 시작했습니다.
2. 스프링에서 비동기 처리를 하는 방법
2-1. @Async 애노테이션
스프링에서 가장 간단하게 비동기 처리를 구현할 수 있는 방법 중 하나가 @Async입니다.
- 예시:
@Service public class MyService { @Async public void doAsyncTask() { // 오래 걸리는 작업 System.out.println("Async Task Running in Thread: " + Thread.currentThread().getName()); } }
- 이걸 적용하려면, 설정 클래스에 @EnableAsync를 추가해줘야 합니다.
- @Async가 붙은 메서드는 별도의 쓰레드 풀에서 실행되기 때문에 메인 쓰레드를 블로킹하지 않습니다.
2-2. 쓰레드 풀 커스터마이징
- 기본적으로는 스프링이 제공하는 SimpleAsyncTaskExecutor를 쓰지만, 성능 최적화를 위해서 쓰레드 풀(ThreadPoolTaskExecutor) 설정을 커스터마이징하기도 합니다.
- 예시:
@Configuration @EnableAsync public class AsyncConfig { @Bean(name = "threadPoolTaskExecutor") public Executor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); executor.setThreadNamePrefix("MyExecutor-"); executor.initialize(); return executor; } }
- 이렇게 하면 특정 상황(예: 대량 트래픽)이 발생해도, 미리 설정된 풀 내에서 쓰레드가 효율적으로 관리됩니다.
3. 배포 환경에서의 고려사항
처음엔 로컬에서 테스트만 했을 땐 잘 돌아갔는데, 막상 AWS EC2 서버에 배포하고 실제 트래픽을 받아보니까 몇 가지 문제가 있었습니다.
- 로그 관리: 쓰레드가 여러 개 돌아가다 보니 로그가 섞여서 보기 힘들었습니다. 그래서 로깅 시 쓰레드 이름이 나오도록 logging.pattern 등을 설정했습니다.
- 서버 자원 모니터링: CPU 사용량이나 메모리를 어디까지 쓰고 있는지 지속적으로 모니터링해야 했습니다. 스프링 자체 로그나 AWS CloudWatch를 활용해서 알람을 설정했습니다.
- 예외 처리: 비동기 메서드 내에서 예외가 발생해도 호출 쪽에는 바로 전파되지 않아서, 비동기용 예외 처리 핸들러(AsyncUncaughtExceptionHandler)를 구현했습니다.
4. 마무리
- 이번에 비동기 로직을 도입하면서, “단순히 쓰레드만 쓰면 되는 게 아니구나”를 뼈저리게 느꼈습니다.
- @Async나 쓰레드 풀 설정만 잘 한다고 끝이 아니라, 실서버 모니터링과 예외 처리 흐름, 로그 관리 등을 종합적으로 신경 써야 했습니다.
- 그래도 한 번 경험해보니, 앞으로는 대규모 트래픽에 좀 더 자신 있게 대응할 수 있을 것 같습니다.
'🗄️ Backend > Spring' 카테고리의 다른 글
Spring과 Spring Boot의 차이점 (1) | 2025.02.08 |
---|---|
Spring Boot 아키텍처 : Entity, DTO, Repository, Service, Controller 흐름과 활용 (1) | 2025.01.28 |
Spring Boot 기초: 웹 애플리케이션 설정 (0) | 2024.11.10 |
HikariCP, MyBatis를 활용한 데이터베이스 연결 풀 설정 및 최적화 (1) | 2024.11.10 |
스프링 프레임워크에서 Redirect, Request, Response 처리 및 서비스 계층 구현 (8) | 2024.11.09 |