도메인 간 상호작용

망고·2024년 8월 21일
post-thumbnail

브로커가 필요하다

기존에 구성한 MSA는
배포와 운영이 도메인 서버별로 나뉘어 있긴 하지만
각 도메인 간 상호작용이 적어,
중앙에 별도의 브로커를 둘 필요성이 적었다.

프로필 이미지 구현 방식을 고민하던 중,
차후에 Board와 생성형 이미지(AI 파트 서버)에도
이미지 CRUD 로직을 적용하려면
구현 시에 따로 이미지 서버를 분리하는 편이 낫겠다고 판단

하지만 이미지 서버를 분리할 경우
여러 도메인(Auth, Board, genarated_image)과
연관된 로직이 발생하기 때문에

현재의 멀티 모듈 구조로선
로직 구현이나 의존성이 꼬일 가능성이 높았다.
(구성하는 과정에서 정말 많이 겪었던 문제..)

덤으로 AI 서버는 파이썬으로 작성될테니
모듈 간 의존성으로 코드를 재사용하기엔 한계가 분명.

이미지 서버를 별도의 도메인으로 분리해 서비스 간 독립성과 유연성을 보장하되, 도매인 간 상호작용을 원할히 유지하기 위해 브로커를 도입하기로 결정.

기존 MSA를 이벤트 드리븐으로 전환하기 위한
초석을 깔기 좋은 기회기도 하니 이참에 메시지 브로커를 선정하고 빠르게 도입해보자!

어떤 브로커가 적합한가

이벤트 브로커로는
RabbitMQ, Kafka, Redis Pub/Sub가 유명하다.

Redis Pub/Sub의 경우
이벤트 브로커의 역할보단
실시간 읽기 성능과 캐싱에 적합한 툴이라 여겨져 제외.

빠른 복원력과 확장성 면에서는
RabbitMQ와 Kafka가 우수하다 판단해 선택지를 둘로 좁혔다.
RabbitMQ와 Kafka의 쓰임을 비교하면 아래와 같다.


kafkarabbitMQ
아키텍처복잡한 메시지 라우팅에 강점을 가진 설계처리량이 많은 스트림을 실시간으로 처리하기 위한 파티션 기반 설계
메시지 처리메시지 사용을 모니터링하여 사용된 메시지를 삭제, 메시지 우선 순위 지원오프셋 트래커를 사용하여 메시지 검색을 추적. 보전 정책에 따라 메시지를 보관. 메시지 우선 순위 X
성능짧은 지연시간. 초당 수 천개의 메시지를 전송초당 수백만 개의 메시지를 실시간으로 전송
프로토콜 및 언어 의존성광범위한 언어 및 레거시 프로토콜을 지원언어 선택의 폭이 제한적. TCP를 통한 바이너리 프로토콜을 데이터 전송에 사용

이미지 서비스의 경우, 실시간 성능보단 데이터 정합성을 고려한 안정성이 우선일 것이라 판단.

라우팅 과정도 (Auth || Board || ImageAI) <-> 이미지 도메인으로
1:1 관계를 구성하기에 복잡도도 낮다.

차후 Batch를 활용한 일괄 알림 서버의 확장을 고려하면
RabbitMQ보다 Kafka가 더 안정적인 선택지라고 여겨져 Kafka로 채택.
인프라 파트에서 여유가 된다면 로깅 서버를 붙이기도 용이한 건 덤.


📗 카프카 구성 요소

토픽(Topic)

  • 토픽은 데이터 카테고리를 나타내는 논리적 구분
  • 각 토픽은 여러 파티션으로 나뉘며 데이터의 병렬 처리를 가능하게 함
  • 프로듀서는 특정 토픽에 이벤트를 발행하고 컨슈머는 해당 토픽을 구독하여 메시지를 수신

프로듀서(Producer)

  • 프로듀서는 Kafka에 메시지를 발행하는 클라이언트
  • 메시지를 특정 토픽에 전송하며, 필요에 따라 파티션을 지정

컨슈머(Consumer)

  • 컨슈머는 Kafka로부터 메시지를 수신하는 클라이언트
  • 컨슈머 그룹을 통해 메시지의 로드 밸런싱과 중복처리 방지를 구현 가능
  • 컨슈머 그룹 내에서는 동일한 파티션의 메시지가 하나의 컨슈머에게만 전달

브로커(Broker)

  • 브로커는 Kafka 서버의 단일 인스턴스를 의미, 여러 브로커가 모여 kafka 클러스터를 구성
  • 브로커는 데이터의 저장과 전송을 담당, 클러스터 내에서 토픽과 파티션을 관리

파티션(Partition)

  • 토픽은 여러 파티션으로 분할되어 저장
  • 각 파티션은 순서가 보장되는 로그 스트림이며, 이를 통해 병렬 처리와 확장성을 제공
  • 파티션 내에서는 메시지의 순서가 보장되지만, 파티션 간의 순서는 보장 X

오프셋(Offset)

  • 오프셋은 각 파티션 내에서 메시지의 고유 식별자
  • 컨슈머는 오프셋을 기반으로 메시지의 처리 상태를 관리

주키퍼(Zookeeper)

  • 주키퍼는 Kafka 클러스터의 상태를 관리하는 데 사용되는 분산 코디네이션 서비스
  • Kafka 브로커의 메타데이터 관리, 리더 선출, 토픽과 파티션 정보 유지, 컨슈머 오프셋 관리 등의 관리자 역할을 담당
  • Kafka는 주키퍼를 통해 브로커 간의 상태를 조율하고, 장애가 발생했을 때 클러스터의 안정성을 유지
  • 2.8 버전 이후로 KRaft 모드가 도입되어 주키퍼 없이도 Kafka 운영이 가능

📚참고 자료

0개의 댓글