SpringBoot 비동기(Async) 처리

2025. 1. 17. 17:45·🗄️ Backend/Spring

 

비동기(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 서버에 배포하고 실제 트래픽을 받아보니까 몇 가지 문제가 있었습니다.

  1. 로그 관리: 쓰레드가 여러 개 돌아가다 보니 로그가 섞여서 보기 힘들었습니다. 그래서 로깅 시 쓰레드 이름이 나오도록 logging.pattern 등을 설정했습니다.
  2. 서버 자원 모니터링: CPU 사용량이나 메모리를 어디까지 쓰고 있는지 지속적으로 모니터링해야 했습니다. 스프링 자체 로그나 AWS CloudWatch를 활용해서 알람을 설정했습니다.
  3. 예외 처리: 비동기 메서드 내에서 예외가 발생해도 호출 쪽에는 바로 전파되지 않아서, 비동기용 예외 처리 핸들러(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
'🗄️ Backend/Spring' 카테고리의 다른 글
  • Spring과 Spring Boot의 차이점
  • Spring Boot 아키텍처 : Entity, DTO, Repository, Service, Controller 흐름과 활용
  • Spring Boot 기초: 웹 애플리케이션 설정
  • HikariCP, MyBatis를 활용한 데이터베이스 연결 풀 설정 및 최적화
hjwjo
hjwjo
백엔드 및 풀스택 개발에 관심 있는 초보 개발자의 개발 블로그입니다.
  • hjwjo
    Jeongwoo's Devlog
    hjwjo
  • 전체
    오늘
    어제
    • Devlog
      • 🗄️ Backend
        • Java
        • Spring
        • JPA
        • SQL
        • JSP
        • AWS
        • GCP
        • Linux
        • GitHub
        • ML
        • Security
      • 🖥️ Frontend
        • React
        • CSS
      • 🏅 Project
        • Hackathon
        • Team Project
      • 📊 Algorithm
        • BOJ
      • 📜 Certs
        • ADsP
        • SQLD
        • 정보처리기사
      • 📖
        • JavaScript
      • 일상
        • 면접후기
  • 블로그 메뉴

    • 홈
    • Devlog
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    java
    springboot
    DML
    자바
    스프링부트
    백준
    jsp
    GCP
    백엔드
    SQL
    http
    스프링
    Spring
    정처기
    정보처리기사
    쿼리
    AWS
    java기초
    ADsP
    데이터베이스
  • 최근 댓글

  • 최근 글

hjwjo
SpringBoot 비동기(Async) 처리
상단으로

티스토리툴바