AM 기반 MSA 기술 여덟번째 정규수업

오리·2026년 7월 30일

LG AM Inspire camp 5기

목록 보기
26/35

오늘 학습한 내용

오늘은 기존 Spring Cloud MSA 프로젝트를 Kafka 기반의 이벤트 처리 구조로 확장하는 실습을 진행했다. 이전까지는 Kafka Connect를 이용하여 데이터베이스 간 데이터 동기화를 실습했다면, 오늘은 실제 Microservice 간 이벤트를 Kafka를 통해 전달하는 구조를 구현하기 시작했다. 또한 RabbitMQ 기반 설정을 제거하고 Kafka 환경으로 변경하는 과정과 Kafka 메시지를 직접 확인하는 방법까지 함께 학습하였다.


RabbitMQ 제거 및 Kafka 환경 구성

기존 프로젝트에서는 Spring Cloud Bus를 사용하기 위해 RabbitMQ를 사용하고 있었지만, Kafka를 이용한 이벤트 기반 통신을 위해 RabbitMQ 의존성을 제거하였다.

변경 내용

  • RabbitMQ 관련 Dependency 제거
  • RabbitMQ 설정 주석 처리 또는 삭제
  • Kafka Producer 설정 추가

application.yml에 Kafka Producer 설정을 추가하였다.

spring:
  kafka:
    bootstrap-servers: localhost:9092

    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer

Kafka Broker의 주소를 지정하고 Producer가 메시지를 직렬화하여 전송할 수 있도록 Serializer를 설정하였다.


JWT 및 Security 설정 확인

Kafka 실습 이전에 기존 서비스들이 정상적으로 동작하는지 확인하였다.

확인한 내용은 다음과 같다.

  • WebSecurity 설정
  • JWT token-secret 확인
  • 회원가입 및 로그인 기능 확인
  • API Gateway를 통한 인증 확인

JWT Secret 값은 Gateway와 User Service에서 동일하게 사용되어야 정상적으로 토큰 검증이 가능하다.


Eureka 등록 문제 해결

실습 도중 Order Service가 정상적으로 실행되었음에도 API Gateway에서 다음과 같은 오류가 발생하였다.

503 Service Unavailable
Unable to find instance for ORDER-SERVICE

처음에는 Order Service 자체가 실행되지 않은 것으로 생각했지만 실제로는 서비스는 실행되고 있었다.

확인한 내용은 다음과 같다.

  • application.yml의 Eureka 설정 확인
  • spring.application.name 확인
  • register-with-eureka
  • fetch-registry
  • prefer-ip-address 설정 확인
eureka:
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1

  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

    register-with-eureka: true
    fetch-registry: true

이후 Eureka Dashboard를 통해 서비스 등록 여부를 확인하면서 Gateway가 실제 서비스를 조회하는 구조를 다시 이해할 수 있었다.

MSA에서는 서비스가 실행된 것만으로 통신이 가능한 것이 아니라 반드시 Eureka에 등록되고 Gateway가 해당 정보를 조회해야 한다는 점을 다시 확인하였다.


Kafka Connect 동작 원리 복습

Kafka Connect가 unhealthy 상태로 표시되는 문제도 함께 확인하였다.

처음에는 Kafka Connect가 정상적으로 동작하지 않는 것으로 생각했지만 로그를 확인한 결과 실제 Connector는 정상적으로 동작하고 있었다.

로그에서 확인한 내용

  • Sink Connector 실행
  • Topic 구독
  • Sink Table 자동 생성
  • Database Write 성공

반면 Health Check에서는

curl: command not found

오류가 발생하였다.

즉,

Kafka Connect 프로그램
        ↓
정상 실행

Docker Health Check
        ↓
curl 명령 없음
        ↓
unhealthy 표시

라는 사실을 확인하였다.

Docker에서 표시하는 unhealthy 상태가 반드시 프로그램 오류를 의미하는 것은 아니라는 점을 배웠다.


Kafka Connect Source / Sink 구조 이해

기존 Connector 설정을 확인해보니 Source Connector는 다음 테이블만 감시하고 있었다.

table.whitelist = mydb1.users

즉

mydb1.users
        ↓
Kafka Topic
        ↓
mydb2.my_topic_users

만 동작하는 구조였다.

따라서 Order Service에서 생성되는

mydb1.orders

테이블은 Kafka로 전달되지 않았다.

Kafka Connect는 지정한 테이블만 읽어 Topic으로 전달하기 때문에 새로운 테이블을 사용하려면 Connector 설정 역시 변경해야 한다는 점을 이해하였다.


Kafka Consumer를 이용한 Topic 확인

Kafka Broker에 실제 메시지가 전달되는지 확인하기 위해 Console Consumer를 사용하였다.

사용한 명령어

kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic example-catalog-topic \
--from-beginning

옵션 의미

옵션설명
bootstrap-serverKafka Broker 주소
topic조회할 Topic
from-beginningTopic의 처음부터 모든 메시지 조회

이를 통해 Producer가 전송한 이벤트가 실제 Kafka Topic에 저장되는지 직접 확인할 수 있었다.


Kafka를 사용하는 이유

오늘 실습의 핵심은 서비스 간 직접 호출을 Kafka 이벤트 기반 구조로 변경하는 것이다.

기존 구조

Order Service
        │
        ▼
Catalog Service 직접 호출

Kafka 기반 구조

Order Service
        │
        ▼
Kafka Producer
        │
        ▼
Kafka Topic
        │
        ▼
Catalog Service Consumer

이벤트 기반 구조에서는 Order Service가 Catalog Service를 직접 호출하지 않아도 되므로 서비스 간 결합도가 낮아지고 장애 전파를 줄일 수 있다.

또한 Producer와 Consumer가 서로 독립적으로 동작할 수 있어 확장성이 향상된다.


Kafka Connect와 Kafka Producer의 차이

오늘 가장 헷갈렸던 부분이기도 했다.

Kafka Connect

  • Database ↔ Kafka 연동
  • 파일, DB 등의 외부 시스템 연결
  • Connector 설정만으로 데이터 이동
MariaDB
    ↓
Kafka Connect
    ↓
Kafka Topic

Kafka Producer / Consumer

  • 서비스 간 이벤트 전달
  • 애플리케이션 내부 코드에서 직접 사용
  • 주문 생성, 재고 감소 등의 비즈니스 이벤트 처리
Order Service
      ↓
Kafka Producer
      ↓
Kafka Topic
      ↓
Catalog Service Consumer

이 둘은 모두 Kafka를 사용하지만 목적이 완전히 다르다는 점을 이해하였다.


오늘 느낀 점

오늘은 Kafka Connect를 이용한 데이터 동기화와 Spring Kafka를 이용한 서비스 간 이벤트 처리가 서로 다른 기술이라는 점을 명확하게 이해할 수 있었다.

또한 MSA에서는 단순히 서비스를 실행하는 것이 아니라 Service Discovery, API Gateway, Kafka Broker, Producer, Consumer가 모두 정상적으로 연결되어야 전체 시스템이 동작한다는 점을 다시 체감하였다.

앞으로는 Catalog Service와 Order Service 사이를 Kafka 이벤트 기반으로 연결하여 주문 이벤트가 발생하면 자동으로 상품 재고가 감소하는 구조를 구현하게 된다. 이번 실습을 통해 이벤트 기반 아키텍처가 기존 REST 호출 방식보다 서비스 간 결합도를 크게 낮출 수 있다는 점을 이해할 수 있었고, 앞으로 구현할 Kafka Consumer의 동작 방식도 더욱 기대된다.

profile
IT 전공자의 발버둥

0개의 댓글