본문 바로가기
스프링 부트3

스프링 부트 3의 비동기 이벤트 처리

by 굿센스굿 2024. 12. 6.
반응형

 

1. 비동기 이벤트 처리란 무엇인가?

비동기 이벤트 처리(asynchronous event handling)는 특정 이벤트가 발생했을 때, 이를 동기적으로 처리하지 않고 별도의 스레드에서 처리하도록 하여 애플리케이션의 응답성을 높이는 기술입니다. 이 방식은 특히 시간이 많이 걸리는 작업(예: 파일 업로드, 이메일 전송, 데이터 분석 등)에서 효과적입니다.

스프링 부트 3에서는 @EventListener와 함께 비동기적으로 이벤트를 처리할 수 있는 기능을 제공합니다. 이를 통해 코드의 가독성을 유지하면서도 효율적으로 이벤트 기반 비동기 처리를 구현할 수 있습니다.


2. 스프링 부트 3에서 비동기 이벤트 처리의 장점

  • 응답 속도 향상: 클라이언트 요청과 독립적으로 작업을 수행하여 애플리케이션의 응답 속도를 높입니다.
  • 확장성: 비동기 방식은 동시 처리량을 증가시키는 데 유리합니다.
  • 유지보수성: 명확한 이벤트 기반 구조를 통해 코드를 더 이해하기 쉽게 만듭니다.
  • 스프링의 강력한 지원: 스프링이 제공하는 기능을 활용해 복잡한 비동기 로직도 간단히 구현할 수 있습니다.

3. 비동기 이벤트 처리 구현 단계

(1) 이벤트 클래스 작성

먼저, 이벤트 객체를 정의합니다. 이벤트는 ApplicationEvent를 상속하거나 일반 POJO(Plain Old Java Object)로 정의할 수 있습니다.

public class UserRegisteredEvent {  
    private final String email;  
  
    public UserRegisteredEvent(String email) {  
        this.email = email;  
    }  
  
    public String getEmail() {  
        return email;  
    }  
}

위 예제에서는 사용자가 회원가입을 완료했을 때 발행되는 이벤트를 나타냅니다.


(2) 이벤트 발행(Publish)

스프링의 ApplicationEventPublisher를 사용해 이벤트를 발행합니다.

@Service  
public class UserService {  
    private final ApplicationEventPublisher eventPublisher;  
  
    public UserService(ApplicationEventPublisher eventPublisher) {  
        this.eventPublisher = eventPublisher;  
    }  
  
    public void registerUser(String email) {  
        // 회원가입 로직  
        System.out.println("User registered with email: " + email);  
  
        // 이벤트 발행  
        UserRegisteredEvent event = new UserRegisteredEvent(email);  
        eventPublisher.publishEvent(event);  
    }  
}

(3) 이벤트 리스너 작성

이벤트를 처리하는 리스너는 @EventListener를 사용하여 구현합니다. 비동기로 실행하려면 @Async를 추가합니다.

@Component  
public class UserEventListener {  
  
    @Async  
    @EventListener  
    public void handleUserRegistered(UserRegisteredEvent event) {  
        System.out.println("Sending welcome email to: " + event.getEmail());  
        // 이메일 전송 로직  
    }  
}

여기서 @Async를 사용하면 이벤트 처리가 별도의 스레드에서 비동기로 실행됩니다.


(4) 비동기 지원 활성화

스프링에서 비동기를 활성화하려면 @EnableAsync를 사용해야 합니다.

@Configuration  
@EnableAsync  
public class AsyncConfig {  
}

4. 비동기 이벤트 처리의 실제 활용 예시

예시 1: 사용자 알림 시스템

사용자가 특정 작업(예: 게시글 작성)을 완료하면, 서버는 알림 이벤트를 발행하여 푸시 알림이나 이메일을 보냅니다.

public class PostCreatedEvent {  
    private final Long postId;  
  
    public PostCreatedEvent(Long postId) {  
        this.postId = postId;  
    }  
  
    public Long getPostId() {  
        return postId;  
    }  
}  
  
@Async  
@EventListener  
public void handlePostCreated(PostCreatedEvent event) {  
    System.out.println("Sending notification for post ID: " + event.getPostId());  
    // 알림 전송 로직  
}

예시 2: 데이터 백업

사용자가 데이터를 업로드하면, 백그라운드에서 데이터 백업을 수행하도록 비동기 이벤트를 설정합니다.

public class DataUploadEvent {  
    private final String filePath;  
  
    public DataUploadEvent(String filePath) {  
        this.filePath = filePath;  
    }  
  
    public String getFilePath() {  
        return filePath;  
    }  
}  
  
@Async  
@EventListener  
public void handleDataUpload(DataUploadEvent event) {  
    System.out.println("Backing up file: " + event.getFilePath());  
    // 백업 로직  
}

예시 3: 로그 처리 시스템

애플리케이션의 주요 활동을 비동기로 로그에 기록하여 성능 저하를 방지합니다.

public class UserActivityEvent {  
    private final String activity;  
  
    public UserActivityEvent(String activity) {  
        this.activity = activity;  
    }  
  
    public String getActivity() {  
        return activity;  
    }  
}  
  
@Async  
@EventListener  
public void handleUserActivity(UserActivityEvent event) {  
    System.out.println("Logging activity: " + event.getActivity());  
    // 로그 저장 로직  
}

5. 비동기 이벤트 처리 시 주의사항

  1. 예외 처리: 비동기 이벤트에서 발생한 예외는 호출자에게 전파되지 않습니다. 반드시 예외 처리 로직을 구현해야 합니다.
  2. 스레드풀 관리: 비동기 처리는 기본적으로 스레드풀이 필요합니다. 적절히 설정하지 않으면 성능 저하가 발생할 수 있습니다.
  3. 트랜잭션 범위: 비동기 이벤트는 호출자의 트랜잭션 범위 밖에서 실행되므로, 트랜잭션 관리에 주의해야 합니다.

6. 결론

스프링 부트 3의 비동기 이벤트 처리 기능은 애플리케이션의 성능과 확장성을 높이는 데 큰 도움이 됩니다. 비동기 처리를 적절히 활용하면 코드의 복잡성을 줄이고, 시스템의 응답 속도를 향상시킬 수 있습니다. 예제를 참고해 실제 프로젝트에 적용해 보세요!

반응형