본문 바로가기
회고

Kafka를 도입해 MSA 트래픽 병목을 해결한 실전 경험기

by 창따오 2025. 7. 31.
728x90

1. 배경

최근 내가 개발한 MSA 기반 서비스에서, Auth-Service와 User-Service 간 동기 REST API 호출로 인해 트래픽 병목 현상이 발생했다. 회원가입이나 탈퇴와 같은 이벤트가 늘어나면서 서비스 간 통신 부하가 커졌고, 특정 서비스가 느려지면 전체 요청이 지연되는 문제도 있었다.

이 문제를 해결하기 위해 Kafka를 도입해 이벤트 기반의 비동기 통신 구조로 개편하였다.


2. 문제 상황

초기 구조에서는 모든 서비스 간 통신이 REST 기반이었다. 예를 들어, 사용자가 회원가입을 하면 Auth-Service에서 User-Service로 HTTP 요청을 보내 프로필을 생성하는 방식이었다. 하지만 다음과 같은 문제들이 있었다:

  • 요청량 증가 시 User-Service에 트래픽 집중
  • User-Service의 응답 지연이 Auth-Service 전체 응답 지연으로 이어짐
  • 서비스 간 결합도가 높아 유지보수가 어려움

이로 인해 실제 운영환경에서 병목 현상이 자주 발생했고, 구조적인 개선이 필요했다.


3. Kafka 도입 및 이벤트 기반 구조 개편

Kafka는 비동기 메시지 큐 역할을 하며, 발신자와 수신자를 느슨하게 연결해준다. 다음과 같은 구조로 개선했다:

  • Auth-Service에서 회원가입/탈퇴 등의 이벤트 발생 시 Kafka 토픽에 메시지를 발행
  • User-Service는 해당 토픽을 구독하고 이벤트를 비동기적으로 수신하여 처리

사용한 Kafka 토픽

  • user.created
  • user.deleted

예시 DTO

public class UserDeletedEvent {
    private Long userId;
    private String email;
    private String reason;
}

 


4. 실제 이벤트 흐름

Auth-Service 측

  • 회원 탈퇴 시 Auth DB에서 유저 정보 삭제 후 Kafka로 user.deleted 이벤트 발행
kafkaTemplate.send("user.deleted", new UserDeletedEvent(userId, email, "탈퇴"));

User-Service 측

  • Kafka Listener를 통해 해당 이벤트를 수신하고 프로필 및 리소스를 정리
@KafkaListener(topics = "user.deleted")
public void consume(UserDeletedEvent event) {
    userProfileService.deleteByUserId(event.getUserId());
}

5. 운영 환경 구성

Kafka, Zookeeper는 Docker Compose로 구성하고, 각 마이크로서비스는 GitHub Actions를 이용해 CI/CD 파이프라인을 구축하였다. GitHub에 push하면 Docker 이미지로 빌드되고, 자동으로 배포되도록 설정하였다.

Kafka 메시지 발행과 소비가 잘 동작하고 있으며, 서비스 간 지연 없이 이벤트가 잘 처리되고 있다.


6. 개선 효과

항목개선 전개선 후

트래픽 부하 특정 서비스에 집중됨 분산 처리 가능
응답 속도 전체 요청 지연 Auth-Service는 빠르게 응답 종료
결합도 높음 (동기 호출) 낮음 (비동기 메시지)
장애 전파 한 서비스 장애가 전체에 영향 느슨한 연결로 복구 유연

7. 회고

Kafka를 통해 서비스를 느슨하게 연결하고, 비동기 이벤트 기반으로 처리함으로써 병목 문제를 효과적으로 해결할 수 있었다. 메시지 유실 방지, 장애 대응, 확장성 면에서도 만족스러운 구조였다.

앞으로는 Dead Letter Queue, Schema Registry, Exactly Once 처리와 같은 고급 기능도 점진적으로 도입해볼 계획이다.