@Async 30초 만에 비동기 — CAP Java 백그라운드 처리 #shorts #SAP #CAP

Moderator

이 글이 답하는 질문

  • CAP Java에서 무거운 작업을 비동기로 처리하려면?
  • @Async를 붙이기만 하면 되는가?
  • 비동기 메서드가 작동하지 않는 이유는 무엇인가?

@Async란

Spring Boot에서 메서드에 @Async를 붙이면 해당 메서드가 별도 스레드에서 실행된다. 이메일 발송, 파일 처리, 대용량 계산처럼 응답 속도에 영향 주는 작업을 백그라운드로 분리할 때 사용한다.

직접 해보기

1. @EnableAsync 활성화

// Application 클래스 또는 @Configuration 클래스에 추가
@SpringBootApplication
@EnableAsync
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2. @Async 메서드 작성

@Service
public class NotificationService {

    @Async
    public CompletableFuture sendEmail(String to) {
        // 오래 걸리는 처리
        Thread.sleep(3000);
        return CompletableFuture.completedFuture("sent to " + to);
    }

    @Async
    public void fireAndForget(String payload) {
        // 반환값 없어도 OK
        process(payload);
    }
}

3. 호출 방법

@Autowired
private NotificationService notificationService;

// 비동기 호출 — 즉시 반환
CompletableFuture future = notificationService.sendEmail("user@example.com");

// 결과가 필요한 경우
String result = future.get(); // 완료될 때까지 블로킹

삽질 노트

  • 같은 클래스 내부 호출은 비동기 작동 안 함 — Spring은 프록시로 @Async를 처리하는데, 자기 자신을 직접 호출하면 프록시를 우회함. 반드시 다른 빈(Bean)에서 호출해야 함
  • @Async 메서드는 private이면 안 됨 — Spring 프록시가 오버라이드할 수 없어 그냥 동기 실행됨
  • 기본 스레드 풀은 무제한. 부하 테스트 전에 TaskExecutor로 풀 크기를 명시적으로 제한할 것

핵심 한 줄

@Async 한 줄로 비동기 처리 가능 — 단, @EnableAsync 활성화 + 외부 빈에서 호출 필수.

더 파볼 주제

  • ThreadPoolTaskExecutor 설정으로 스레드 풀 조정
  • CompletableFuture.allOf()로 여러 비동기 작업 병렬 처리
  • @Async 예외 처리 — AsyncUncaughtExceptionHandler