메시지 중심 분산 시스템 아키텍처

여행 비즈니스 시스템은 필연적으로 많은 상품 공급처 및 판매 채널과 연동되며 주고 받는 데이터는 복잡하고 많습니다. 현재 오마이트립이 운영하는 시스템은 데이터를 정적 상태로 다루고 있으며 구성요소들 간 소통은 웹 API 호출에 의존합니다. 이런 방식은 점점 한계에 부딛히고 문제를 일으킵니다. 기준 데이터 변경은 운영 중인 시스템의 성능을 심각하게 저하시키고, 스케줄링에 의한 데이터 수집은 요금 정보 불일치로 인한 수익 감소를 야기하기도 합니다. 메시지 중심의 분산 아키텍처는 이것들을 해결할 효과적인 방법 중 하나입니다.

메시지 중심 시스템

오늘날 마이크로서비스 아키텍처(Microservice Architecture)등을 사용한 많은 분산 시스템은 웹 API를 통해 연동됩니다. 이런 구조는 다음의 단점을 가집니다.

  • 웹 API 호출은 요청과 응답의 쌍으로 이뤄지고 이는 비동기 작업 절차에 적합하지 않습니다. 웹 API를 통해 비동기 요청을 표현하는 것이 불가능하진 않지만 가장 어울리는 방법은 아니며 클러스터를 대상으로 메시지 순서를 보장하지 못합니다.
  • 요청자 서비스는 항상 응답자 서비스의 참조(API 끝점)를 알아야 합니다. 이로 인해 불필요한 결합이 발생하고 의존 관계가 복잡해집니다.
  • 장애 전파에 취약합니다. API 요청자 서비스는 응답자 서비스가 불능 상태가 되면 함께 불능 상태에 빠지며 전체 절차가 실패하게 됩니다.

메시지 스트림 기반의 분산 시스템은 다음의 장점을 가집니다.

  • 비동기 작업 절차에 적합하며 작업 절차와 자원 규모를 확장하기 쉽고 일련의 메시지 전달 순서를 보장합니다.
  • 비동기 메시지 전달을 통해 서비스는 서비스 경계 밖의 대상에 대한 결합을 제거하며 의존 관계는 단순해집니다.
  • 메시지 발신자 서비스는 메시지 수신자 서비스의 불능 상황에 영향받지 않습니다. 일시적 장애는 수신자 서비스의 경계를 벗어나지 않으며 전체 절차는 지연이 발생할 뿐 결국에는(eventually) 완료됩니다.

다양한 외부 서비스와 연동되며 수시로 데이터를 전달받고 또 전달해야 하는 여행 비즈니스 시스템에 메시지 중심 설계는 효과적입니다. 시스템은 적시에 데이터를 협력 시스템에 전달할 수 있고 연동 대상의 확장과 축소는 내부 구성요소에 영향을 주지 않습니다.

하지만 시스템의 모든 작업에 비동기 메시징이 적합하지는 않습니다. 예를 들어 사용자 인증 작업은 요청에 대응하는 응답의 형태로 결과를 반환하는 것이 바람직하고, 상품 검색 등 요구에 대한 조회 작업에는 웹 API가 훨씬 더 효율적입니다. 그렇기 때문에 시스템을 설계할 때 메시지 스트림과 웹 API를 상황에 맞게 조합하는 것이 좋습니다.

오마이트립 아키텍처 가이드는 다음 다이어그램을 통해 메시지 스트림과 웹 API를 사용한 분산 시스템 설계를 소개합니다.

메시지 스트림과 웹 API를 사용한 분산 시스템 설계

메시지 스트림과 웹 API를 사용한 분산 시스템 설계

메시지 중심 시스템의 구성요소 서비스

오마이트립 아키텍처 가이드는 다음과 같이 서비스 구성을 제안합니다.

메시지 중심 시스템의 구성요소 서비스

메시지 중심 시스템의 구성요소 서비스

메시지 중심 시스템 설계는 서비스 응용프로그램 형태에 영향을 줍니다. 웹 API에만 의존하는 시스템이라면 구성요소 서비스는 항상 웹 응용프로그램 형태로 제한됩니다. 하지만 메세지 중심 시스템은 웹 응용프로그램, 작업자 호스트, 서버리스(Serverless) 함수 응용프로그램 등 다양한 형태의 서비스 응용프로그램을 허용합니다.

경우에 따라 서비스는 하나 이상의 서로 다른 형태의 응용프로그램을 가집니다. 예를 들어 서비스가 CQRS(Command and Query Responsibility Segregation) 패턴을 사용한다고 가정합니다. 이 서비스를 개발하는 팀은 명령 스택은 작업자 호스트로 만들고, 조회 스택은 서버리스 함수 응용프로그램 집합으로 이뤄진 읽기 모델 생성기와 조회 기능을 제공하는 웹 API 응용프로그램을 조합해 구축할 수 있습니다.

오마이트립 기술조직은 변화와 성장을 함께할 인재를 찾고 있습니다. 관심 있는 분들은 채용 페이지에 방문하세요.

서비스 계약 분리

서비스는 다른 서비스와 메시지를 주고 받기 위해 메시지를 정의합니다. 이 메시지 정의를 서비스 계약이라 부릅니다. 서비스 계약이 다른 서비스와 공유되어야 메시지가 올바르게 생성되고 소비됩니다. 문서화를 통해 서비스 계약을 공유할 수 있습니다. 하지만 코드와 문서가 항상 일관됨을 보장하는 것은 쉽지 않습니다. 따라서, 동일한 플랫폼이나 프로그래밍 언어를 사용하는 서비스와 같이, 서비스 계약 코드 자체를 공유할 수 있는 경우에는 이 방법을 가장 먼저 고려해야 합니다. 그런데 이런 경우 서비스 계약과 도메인 모델이 같은 바이너리에 포함되면 도메인 논리가 서비스 외부로 노출되어 오용될 가능성이 있고 순환참조의 위험을 가집니다.

서비스 계약을 도메인 모델에서 별도의 프로젝트로 분리하면 이 문제가 해결됩니다. 서비스 계약 프로젝트는 오직 메시지 정의만 담으며 논리는 전혀 포함하지 않습니다. 서비스 계약 프로젝트들은 서로 참조하지 않으며 하나의 서비스 계약 프로젝트는 여러 서비스의 도메인 모델 프로젝트에 의해 참조될 수 있습니다.

서비스 계약

서비스 계약

대부분의 메시지는 명령과 이벤트로 구분됩니다. 명령은 서비스에 어떤 행위를 요구하는 메시지로 명령을 수신하는 서비스가 정의하고, 이벤트는 서비스에서 발생된 과거의 사실을 표현하며 이벤트를 발행하는 서비스가 정의합니다.

시스템 간 메시징

오마이트립의 모든 서비스가 하나의 시스템으로 묶여 메시징 인프라를 공유하는 것은 바람직하지 않습니다. 서비스가 관심대상이 아닌 메시지를 수신하기 위해 소비하는 컴퓨팅 자원이 과도하게 커질 수 있고 하나의 메시지 스트림 장애가 회사 전체 서비스를 중단시킬 수도 있습니다.

하지만 어떤 메시지들은 시스템 경계를 벗어나 다른 시스템에 전달되는 것이 좋습니다. 예를 들어, 항공 상품 시스템과 호텔 상품 시스템이 있을 때 두 시스템이 가진 대다수의 메시지는 각 시스템 내부에서만 유용한 반면 일부 메시지는 결합 상품 시스템과 정산 시스템이 관심을 가질 수 있습니다.

각 시스템에 메시지 포트를 설치하고 이 메시지 포트들을 중앙 메시지 허브에 연결해 이 요구사항을 충족시킬 수 있습니다.

시스템 간 메시징

메시지 포트는 시스템 내부에서 발생하는 메시지 중 일부를 메시지 허브로 전달하고, 메시지 허브로부터 전달받은 메시지 중 일부를 시스템 내부로 들여보내는 역할을 담당합니다.

정리

오마이트립은 복잡한 여행 비즈니스 도메인을 효율적으로 구현할 새 시스템을 구축할 계획이며, 이를 지원하기 위해 메시지 중심 아키텍처를 준비하고 있습니다. 우리는 비동기 메시징의 적극적인 활용이 시스템의 유연함과 지속 가능성 및 확장성을 높이고 결과적으로 기민한 변화 대응을 통해 비즈니스 원동력이 될 것으로 기대합니다.

CQRS와 이벤트 소싱(Event Sourcing)은 그 자체로도 장점을 가지지만 메시지 중심 아키텍처와 서로 매우 잘 들어맞습니다. 오마이트립 기술 조직은 CQRS와 이벤트 소싱에도 많은 투자를 할 것입니다.

오마이트립 기술조직은 변화와 성장을 함께할 인재를 찾고 있습니다. 관심 있는 분들은 채용 페이지에 방문하세요.

참고자료