내가 운영하는 구조는 완전한 MSA라기보다는, 모놀리식과 일부 분리된 서비스가 공존하는 하이브리드 구조에 가깝다.
display-api, order-api, ssr 등은 서비스 단위로 나뉘어 있지만, 데이터베이스나 레거시 도메인 의존성이 완전히 분리되어 있지는 않기 때문이다.

 

정리해보기 전에 우선 MSA가 뭔지 좀 생각해보자.

MSA의 핵심은?

  1. 서비스 독립성.
    • 각 서비스가 DB서버가 분리되어져있고, 독립적으로 배포됨
    • 모놀리식은 하나의 코드베이스에 모든 기능이 묶여 있어서 장바구니 버그 하나가 주문 전체를 죽이는 구조
  2. 서비스 간 통신
    • 직접 함수 호출 대신 Rest API(동기) 또는 Kafka 같은 메시지 브로거(비동기)로 통신
  3. 장애 격리
    • Circuit Breaker가 특정 서비스 장애가 전체로 번지지 않도록 차단.

 

현재 내 상황

  • DB 분리 여부?
    • MSA에서 제일 중요한 포인트 중 하나인 서비스별 DB 소유권이 없다
    • MSA라고 부르기 위해서는 단순히 API 서버가 여러 개로 나뉜 것만으로는 부족하고 각 서비스가 자신의 데이터를 직접 소유하고,다른 서비스의 DB를 참조하지 않아야 하지만 현재는 그런 상태가 아니다
  • 분산 모놀리식?
    • 내가 처한 상태와 비슷한 걸 서버는 여러 개로 나뉘었지만, 배포·DB·도메인 규칙·장애 영향도가 여전히 강하게 묶여 있다면 이것은 MSA라기보다 분산 모놀리식에 가깝다.

 

하지만 MSA를 한다고 무조건 좋을까?

  • 네트워크 호출 실패 가능성
    • 모놀리식은 함수 호출이지만 MSA는 네트워크 호출이다.
    • 따라서, 나는 FeignClient로 추천 API를 호출할 때 Circuit Breaker를 걸었고, fallback을 빈 리스트로 처리하여 장애 및 실패 가능성에 대비한 구조로 개발했다
  • API 응답 지연
    • 네트워크 레이턴시가 추가된다.
    • 모놀리식은 서버 안에서 함수를 호출하기 때문에 레이턴시가 거의 0입니다. 하지만 MSA는 서비스 간 호출할 때마다 네트워크를 타고, 호출이 3번이면 레이턴시도 3번 누적된다.

  • 데이터 정합성 관리 어려움
    • 모놀리식은 주문 생성, 장바구니 비우기, 재고 차감을 하나의 트랜잭션으로 묶을 수 있는 구조이다.
    • MSA는 DB가 분리되면 묶고 싶어도 묶을 수 없는 구조입니다. DB가 서비스마다 다르니까 Spring @Transactional 이 아예 작동하지 않는다. 트랜잭션 자체가 DB 단위로 묶이기 때문입니다.
      • 해결방법 : saga패턴, outbox패턴
      • Saga 패턴은 각 서비스가 실패 시 보상 트랜잭션을 실행하는 방식
      • 아웃박스 패턴은 이벤트를 DB에 먼저 저장하고 Kafka로 발행해 원자성을 보장하는 방식
      • 면절 질문 : DB 분리하면 어떻게 정합성 보장할 건가요?
  • 로그 추적 어려움
    • 모놀리식 로그는 한 곳에 있지만, MSA는 서비스마다 로그가 흩어진다. 
  • 배포 단위는 나뉘었지만 장애 원인 파악은 더 어려워짐
    • 이건 앞의 로그 추적 어려움과 연결된다. 독립 배포가 가능해진 대신, 어느 서비스의 어느 배포가 문제를 일으켰는지 파악하는 복잡도가 올라간다
  • 운영 복잡도 증가
    • 서비스가 늘어날수록 모니터링, 배포 파이프라인, 인프라 관리 비용이 급격히 올라간다.

완전한 MSA가 필요한 시점은?

  • 서비스 규모가 커져서 팀이 서로 방해가 될 때, DB를 공유하면 한 팀이 스키마를 바꿨을 때 다른 팀 서비스가 터진다.
  • 서비스별로 트래픽 차이가 극단적일 때, 쿠팡이츠로 예를 들면 주문 서비스는 점심/저녁 피크에 폭발적으로 트래픽이 몰리지만, 정산 서비스는 하루 한 번 돌아도 된다. DB까지 분리해야 주문 서비스만 독립적으로 스케일 아웃이 가능하다.

 

우리 조직?

우리 조직에서는 DB까지 분리하기에는 비합리적이다. 팀이 1개밖에 없고, 파트도 업무도 분리되어져 있지 않고, MAU도 너무 낮다. 너무 복잡도가 높아질 확률이 높다. 그래서 우리는 DB를 공유하는 논리적 MSA단계였던 것 같다. 팀 규모와 서비스 성숙도를 고려했을 때 당시에는 합리적인 선택이었고, DB 분리는 서비스가 더 성장하고 팀 간 의존성이 문제가 되는 시점에 Saga 패턴과 함께 가져가야 할 다음 과제로 인식하고 있다.

+ Recent posts