, ,

[설계 판단] 미디어 평면과 비즈니스 평면을 두 서비스로 쪼갠 이유

결론 먼저 — 한 서비스 vs 두 서비스, 4축 비교

한 서비스 두 서비스 분리
장애 격리 한쪽이 죽으면 둘 다 격리됨
배포 주기 가장 느린 쪽에 묶임 독립
의존성 그래프 코드 안에서 얽힘 네트워크 경계로 강제 분리
디버깅 시 의심 범위 전체 코드베이스 신호 따라 좁아짐
초기 코드 라인 적음 약간 늘어남

분리는 코드를 늘리는 결정이 아니라, 코드 변경의 결을 가지런하게 만드는 결정이다.

미디어 평면과 비즈니스 평면, 무엇이 다른가

미디어 평면 (media plane)

  • RTP forward, ICE 협상, codec, panic 격리
  • 한 통화의 latency가 사용자 경험에 직결
  • 에러 = 즉시 통화 실패 (동기적 영향)

비즈니스 평면 (control / business plane)

  • 세션 메타(누가 누구에게, 언제), 권한, billing, 통계 집계
  • “통계가 1초 늦게 들어와도 사용자가 모른다”가 허용되는 환경
  • 에러 = 후속 처리 지연 (eventual consistency 허용)

이 둘은 시간 축의 단위가 다르다. 미디어는 ms 단위, 비즈니스는 초~분 단위. 같은 프로세스에 두면 더 빡빡한 SLA에 양쪽 다 묶이게 된다.

같이 두면 무슨 일이 생기나

데모를 짤 때 처음에는 한 프로세스에 두 책임을 다 넣어 봤다. 코드량은 작아 보였지만 곧 두 가지 부담이 드러났다.

  1. 비즈니스 로직 한 줄을 고치려고 미디어 프로세스까지 재시작해야 한다 → 진행 중인 데모 통화가 끊김
  2. 비즈니스 평면의 e2e 테스트가 도는 동안 미디어 코드가 굳어 있다
  3. 한쪽 panic이 다른 쪽까지 죽인다

코드량이 작을 때는 잘 보이지 않는 이 비용이, 데모를 며칠 굴리는 사이에 누적된다는 게 핵심이었다.

두 서비스를 어떻게 잇나 — 3가지 패턴

패턴 장점 단점
직접 RPC (gRPC / HTTP) 단순, 디버깅 쉬움 강결합, 서비스 간 빌드/테스트 복잡
메시지 큐 (NATS / RabbitMQ / Kafka) 비동기, 부하 분산 자연스러움 복잡도 증가, 메시지 추적 도구 필요
공유 DB / Redis 가장 가벼움 책임 경계가 흐려짐, 스키마 변경이 양쪽에 영향

1:1 음성 데모 수준에서는 직접 RPC가 가장 자연스러웠다. 통화 시작·종료 같은 시점 신호만 비즈니스 평면이 받아 두면 충분하기 때문이다.

언제 분리하지 말아야 하나

  • 한 사람이 처음부터 끝까지 짜는 데모 / PoC — 분리 비용이 본질 학습을 가린다
  • 책임이 정말로 한 가지인 작은 도구 — Conway’s Law를 거꾸로 적용하는 셈
  • 두 평면 모두 한 함수 안에 들어가는 수준의 단순 흐름

분리는 무조건 좋은 결정이 아니라, 코드 변경의 결이 갈리기 시작했을 때 의미가 생긴다.

개인 메모 — “한 프로세스 안에서 두 책임이 부딪힐 때”

처음에는 “어차피 도메인이 같으니 한 서비스로 두는 게 단순하지 않나”라고 생각했다. 코드량이 작은 단계에서는 그게 맞았다. 그런데 데모를 며칠 굴리면서 비즈니스 로직 한 줄을 고치려 할 때마다 미디어 코드의 e2e가 같이 도는 부담을 직접 느꼈고, 그제야 두 평면을 가르는 게 의미가 있다는 걸 알게 됐다.

분리한 후로는 한쪽을 만지는 사이 다른 쪽을 신경쓰지 않아도 된다는 단순한 이점이 생각보다 크게 다가왔다. 12-Factor App의 process 분리 원칙이 작은 데모에서도 의미가 있다는 걸 짧은 경험으로 확인한 셈이다.

참고


관련 글

이 글은 9개월 운영한 1:1 AI 음성 상담 시스템 시리즈의 일부입니다. 전체 그림과 학습 순서는 허브에서, 이웃 주제는 아래에서 이어집니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다