모놀리식을 마이크로서비스로 리팩터링

이 참조 가이드는 마이크로서비스 설계, 빌드, 배포에 대한 4부로 구성된 시리즈의 두 번째 문서입니다. 이 시리즈에서는 마이크로서비스 아키텍처의 다양한 요소를 설명하며, 마이크로서비스 아키텍처 패턴의 이점과 단점 및 적용 방법이 포함되어 있습니다.

  1. 마이크로서비스 소개
  2. 모놀리식을 마이크로서비스로 리팩터링(이 문서)
  3. 마이크로서비스 설정의 서비스 간 통신
  4. 마이크로서비스 애플리케이션의 분산 추적

이 시리즈는 모놀리식 애플리케이션을 마이크로서비스 애플리케이션으로 리팩터링하는 마이그레이션을 설계 및 구현하는 애플리케이션 개발자 및 설계자를 대상으로 합니다.

모놀리식 애플리케이션을 마이크로서비스로 변환하는 프로세스는 애플리케이션 현대화의 형식입니다. 애플리케이션 현대화를 위해서는 모든 코드를 동시에 리팩터링하지 않는 것이 좋습니다. 대신 모놀리식 애플리케이션을 점진적으로 리팩터링하는 것이 좋습니다. 애플리케이션을 점진적으로 리팩터링하면 마이크로서비스로 구성된 새 애플리케이션을 점진적으로 빌드하고 모놀리식 애플리케이션과 함께 애플리케이션을 실행하게 됩니다. 이 방식을 Strangler Fig 패턴이라고도 합니다. 시간이 지남에 따라 모놀리식 애플리케이션에서 구현되는 기능의 양은 완전히 사라지거나 다른 마이크로서비스가 될 때까지 축소됩니다.

모놀리식에서 기능을 분리하려면 기능의 데이터, 로직, 사용자에게 표시되는 구성요소를 신중하게 추출하고 새 서비스로 리디렉션해야 합니다. 솔루션 공간으로 이동하기 전에 문제 공간을 제대로 이해하는 것이 중요합니다.

문제 공간을 이해하면 적절한 격리 수준을 제공하는 도메인의 자연스러운 경계를 이해하게 됩니다. 도메인을 완전히 이해하기 전에는 작은 서비스 대신 큰 서비스를 만드는 것이 좋습니다.

서비스 경계 정의는 반복 프로세스입니다. 이 프로세스는 까다로운 작업이기 때문에 얻을 수 있는 이점과 분리 비용을 지속적으로 평가해야 합니다. 모놀리식 분리의 접근 방식을 평가하는 데 도움이 되는 요소는 다음과 같습니다.

  • 모든 것을 한 번에 리팩터링하지 마세요. 서비스 분리의 우선순위를 정하려면 비용과 이점을 평가합니다.
  • 마이크로서비스 아키텍처의 서비스는 기술 문제가 아닌 비즈니스 문제를 중심으로 구성됩니다.
  • 서비스를 점진적으로 마이그레이션할 때 잘 정의된 API 계약을 거치도록 서비스와 모놀리식 간의 통신을 구성합니다.
  • 마이크로서비스에는 훨씬 더 많은 자동화가 필요합니다. 지속적 통합(CI), 지속적 배포(CD), 중앙 로깅, 모니터링에 대해 사전에 고려하세요.

다음 섹션에서는 서비스를 분리하고 모놀리식 애플리케이션을 점진적으로 마이그레이션하기 위한 다양한 전략을 설명합니다.

도메인 기반 설계로 분리

마이크로서비스는 데이터 액세스 또는 메시징과 같은 수평형 레이어가 아닌 비즈니스 기능을 중심으로 설계해야 합니다. 또한 마이크로서비스는 느슨한 결합과 높은 기능 응집도를 가져야 합니다. 다른 서비스를 동시에 업데이트하지 않고도 한 서비스를 변경할 수 있으면 마이크로서비스가 느슨하게 결합됩니다. 사용자 계정 관리 또는 결제 처리와 같이 잘 정의된 단일 목적이 있는 경우 마이크로서비스는 응집력이 있습니다.

도메인 중심 설계(DDD)를 사용하려면 애플리케이션이 작성되는 도메인에 대해 잘 이해하고 있어야 합니다. 애플리케이션을 만드는 데 필요한 도메인 지식은 이를 이해하는 사람, 즉 도메인 전문가에게 있습니다.

다음과 같이 DDD 접근 방식을 기존 애플리케이션에 소급 적용할 수 있습니다.

  1. 유비쿼터스 언어, 즉 모든 이해관계자들이 공유하는 공통 어휘를 식별합니다. 개발자로서 기술 지식이 없는 사람이 이해할 수 있는 용어를 코드에 사용하는 것이 중요합니다. 코드에서 달성하고자 하는 내용은 회사 프로세스를 반영해야 합니다.
  2. 모놀리식 애플리케이션에서 관련 모듈을 식별한 다음 해당 모듈에 공통적인 어휘를 적용합니다.
  3. 명확하게 정의된 책임을 가진 식별된 모듈에 명시적 경계를 적용하는 제한된 컨텍스트를 정의합니다. 식별하는 제한된 컨텍스트는 더 작은 마이크로서비스로 리팩터링될 수 있는 후보입니다.

다음 다이어그램은 기존 전자상거래 애플리케이션에 제한된 컨텍스트를 적용하는 방법을 보여줍니다.

제한된 컨텍스트는 애플리케이션에 적용됩니다.

그림 1. 애플리케이션 기능은 서비스로 마이그레이션되는 제한된 컨텍스트로 분리됩니다.

그림 1에서 전자상거래 애플리케이션의 기능은 다음과 같이 제한된 컨텍스트로 분리되고 서비스로 마이그레이션됩니다.

  • 주문 관리 및 처리 기능은 다음 카테고리로 결합됩니다.
    • 주문 관리 기능이 주문 서비스로 마이그레이션됩니다.
    • 물류 배송 관리 기능이 배송 서비스로 마이그레이션됩니다.
    • 재고 기능이 재고 서비스로 마이그레이션됩니다.
  • 회계 기능은 단일 카테고리에 결합됩니다.
    • 소비자, 판매자, 타사 기능은 결합되어 계정 서비스로 마이그레이션됩니다.

마이그레이션 서비스 우선순위 지정

서비스를 분리하기에 적합한 시작점은 모놀리식 애플리케이션에서 느슨하게 결합된 모듈을 식별하는 것입니다. 느슨하게 결합된 모듈을 마이크로서비스로 변환하는 첫 번째 후보 중 하나로 선택할 수 있습니다. 각 모듈의 종속 항목 분석을 완료하려면 다음을 확인하세요.

  • 종속 항목 유형: 데이터 또는 다른 모듈의 종속 항목
  • 종속 항목 규모: 식별된 모듈의 변경사항이 다른 모듈에 미치는 영향

데이터 종속 항목이 큰 모듈을 마이그레이션하는 작업은 중대한 작업으로 간주됩니다. 기능을 먼저 마이그레이션하고 관련 데이터를 나중에 마이그레이션하는 경우 데이터를 일시적으로 여러 데이터베이스에서 읽고 쓸 수 있습니다. 따라서 데이터 무결성 및 동기화 문제를 고려해야 합니다.

다른 모놀리식과 비교 시 리소스 요구사항이 다른 모듈을 추출하는 것이 좋습니다. 예를 들어 모듈에 인메모리 데이터베이스가 있는 경우 모듈을 서비스로 변환하여 더 높은 메모리의 호스트에 배포할 수 있습니다. 특정 리소스 요구사항이 있는 모듈을 서비스로 전환하면 애플리케이션을 훨씬 더 쉽게 확장할 수 있습니다.

운영 측면에서 모듈을 자체 서비스로 리팩터링하는 것은 기존 팀 구조를 조정하는 것을 의미합니다. 책임을 명확하게 하기 위한 가장 좋은 방법은 전체 서비스를 소유한 소규모 팀의 역량을 강화하는 것입니다.

마이그레이션의 우선순위 지정 방식에 영향을 줄 수 있는 추가 요인으로는 비즈니스 중요도, 포괄적인 테스트 범위, 애플리케이션 보안 상태, 조직 승인 등이 있습니다. 평가에 따라 이 시리즈의 첫 번째 문서에 설명된 대로 리팩터링에서 얻을 수 있는 이점에 따라 서비스 순위를 지정할 수 있습니다.

모놀리식에서 서비스 추출

이상적인 서비스 후보를 식별한 후에는 마이크로서비스 및 모놀리식 모듈이 모두 공존할 수 있는 방법을 파악해야 합니다. 이러한 공존을 관리하는 한 가지 방법은 모듈이 함께 작동하는 데 도움을 주는 프로세스 간 통신(IPC) 어댑터를 사용하는 것입니다. 시간이 지나면서 마이크로서비스가 부하를 받아 모놀리식 구성요소를 제거합니다. 점진적인 방식으로 버그 또는 성능 문제를 감지할 수 있으므로 이 점진적인 프로세스를 통해 모놀리식 애플리케이션에서 새 마이크로서비스로 이동하는 위험을 줄일 수 있습니다.

다음 다이어그램은 IPC 접근 방식을 구현하는 방법을 보여줍니다.

IPC 접근 방식은 모듈이 함께 작동하도록 도움을 줍니다.

그림 2. IPC 어댑터는 모놀리식 애플리케이션과 마이크로서비스 모듈 간의 통신을 조정합니다.

그림 2에서 모듈 Z는 모놀리식 애플리케이션에서 추출하려는 서비스 후보입니다. 모듈 X 및 Y는 모듈 Z에 종속됩니다. 마이크로서비스 모듈 X 및 Y는 모놀리식 애플리케이션에서 IPC 어댑터를 사용하여 REST API를 통해 모듈 Z와 통신합니다.

이 시리즈의 다음 문서인 마이크로서비스 설정의 서비스 간 통신에서는 Strangler Fig 패턴 및 모놀리식에서 서비스를 분해하는 방법을 설명합니다.

모놀리식 데이터베이스 관리

일반적으로 모놀리식 애플리케이션에는 자체 모놀리식 데이터베이스가 있습니다. 마이크로서비스 아키텍처의 원칙 중 하나는 마이크로서비스마다 하나의 데이터베이스를 가지는 것입니다. 따라서 모놀리식 애플리케이션을 마이크로서비스로 현대화할 때는 식별한 서비스 경계를 기반으로 모놀리식 데이터베이스를 분할해야 합니다.

모놀리식 데이터베이스를 분할할 위치를 결정하려면 먼저 데이터베이스 매핑을 분석하세요. 서비스 추출 분석 중에 만들어야 하는 마이크로서비스에 대한 유용한 정보를 수집했습니다. 동일한 접근 방식을 사용하여 데이터베이스 사용량을 분석하고 테이블 또는 다른 데이터베이스 객체를 새 마이크로서비스에 매핑할 수 있습니다. SchemaCrawler, SchemaSpy, ERBuilder와 같은 도구는 이러한 분석을 수행하는 데 도움이 됩니다. 테이블 및 기타 객체를 매핑하면 잠재적인 마이크로서비스 경계를 넘나드는 데이터베이스 객체 간의 결합을 이해하는 데 도움이 됩니다.

하지만 데이터베이스 객체 간에 명확한 구분이 없을 수 있으므로 모놀리식 데이터베이스를 분할하는 작업은 복잡합니다. 데이터 동기화, 트랜잭션 무결성, 조인, 지연 시간과 같은 다른 문제도 고려해야 합니다. 다음 섹션에서는 모놀리식 데이터베이스를 분할할 때 이러한 문제에 대응하는 데 도움이 되는 패턴을 설명합니다.

참조 테이블

모놀리식 애플리케이션에서는 모듈이 다른 모듈의 테이블로의 SQL 조인을 통해 다른 모듈의 필수 데이터에 액세스하는 것이 일반적입니다. 다음 다이어그램은 이전의 전자상거래 애플리케이션 예시를 사용하여 SQL 조인 액세스 프로세스를 보여줍니다.

모듈은 SQL 조인을 사용하여 다른 모듈의 데이터에 액세스합니다.

그림 3. 모듈은 데이터를 다른 모듈의 테이블에 조인합니다.

그림 3에서는 제품 정보를 가져오기 위해 주문 모듈이 product_id 외래 키를 사용하여 주문을 제품 테이블에 조인합니다.

하지만 모듈을 개별 서비스로 분해하는 경우 주문 서비스가 제품 서비스의 데이터베이스를 직접 호출하여 조인 작업을 실행하지 않는 것이 좋습니다. 다음 섹션에서는 데이터베이스 객체를 분리할 때 고려할 수 있는 옵션을 설명합니다.

API를 통해 데이터 공유

핵심 기능 또는 모듈을 마이크로서비스로 분리할 때는 일반적으로 API를 사용하여 데이터를 공유하고 노출합니다. 참조된 서비스는 다음 다이어그램과 같이 호출 서비스에 필요한 API로 데이터를 노출합니다.

데이터는 API를 통해 노출됩니다.

그림 4. 서비스는 API 호출을 사용하여 다른 서비스에서 데이터를 가져옵니다.

그림 4에서 주문 모듈은 API 호출을 사용하여 제품 모듈에서 데이터를 가져옵니다. 이 구현에서는 추가 네트워크 및 데이터베이스 호출로 인해 명백한 성능 문제가 발생합니다. 하지만 데이터 크기가 제한된 경우 API를 통한 데이터 공유는 원활하게 작동합니다. 또한 호출된 서비스가 변화율이 잘 알려진 데이터를 반환하는 경우 호출자에 로컬 TTL 캐시를 구현하여 호출된 서비스에 대한 네트워크 요청을 줄일 수 있습니다.

데이터 복제

서로 다른 두 마이크로서비스 간에 데이터를 공유하는 또 다른 방법은 종속 서비스 데이터베이스에 데이터를 복제하는 것입니다. 데이터 복제는 읽기 전용이며 언제든지 다시 빌드할 수 있습니다. 이 패턴을 사용하면 서비스가 보다 일관될 수 있습니다. 다음 다이어그램은 두 마이크로서비스 간의 데이터 복제 작동 방식을 보여줍니다.

데이터는 마이크로서비스 간에 복제됩니다.

그림 5. 서비스의 데이터는 종속 서비스 데이터베이스에 복제됩니다.

그림 5에서는 제품 서비스 데이터베이스가 주문 서비스 데이터베이스에 복제됩니다. 이 구현을 통해 주문 서비스는 제품 서비스에 대한 반복 호출 없이 제품 데이터를 가져올 수 있습니다.

데이터 복제를 빌드하려면 구체화된 뷰, 데이터 캡처 변경(CDC), 이벤트 알림과 같은 기법을 사용하면 됩니다. 복제된 데이터는 eventual consistency를 가지지만 데이터 복제에 지연이 있을 수 있으므로 오래된 데이터가 제공될 위험이 있습니다.

구성으로서의 정적 데이터

국가 코드 및 지원되는 통화와 같은 정적 데이터는 느리게 변경됩니다. 마이크로서비스에서 정적 데이터를 구성으로 삽입할 수 있습니다. 최신 마이크로서비스 및 클라우드 프레임워크는 구성 서버, 키-값 저장소, vault를 사용하여 이러한 구성 데이터를 관리하는 기능을 제공합니다. 이러한 기능은 선언적으로 포함할 수 있습니다.

공유된 변경 가능한 데이터

모놀리식 애플리케이션에는 공유된 변경 가능한 상태라는 일반적인 패턴이 있습니다. 공유된 변경 가능한 상태 구성에서 여러 모듈은 다음 다이어그램과 같이 단일 테이블을 사용합니다.

공유된 변경 가능한 상태 구성은 단일 테이블을 여러 모듈에서 사용할 수 있도록 합니다.

그림 6. 여러 모듈이 하나의 테이블을 사용합니다.

그림 6에서 전자상거래 애플리케이션의 주문, 결제, 배송 기능은 동일한 ShoppingStatus 테이블을 사용하여 고객의 쇼핑 여정에서 주문 상태를 유지합니다.

공유된 변경 가능한 상태 모놀리식을 마이그레이션하려면 별도의 ShoppingStatus 마이크로서비스를 개발하여 ShoppingStatus 데이터베이스 테이블을 관리합니다. 이 마이크로서비스는 다음 다이어그램과 같이 API를 노출하여 고객의 쇼핑 상태를 관리합니다.

API는 다른 서비스에 노출됩니다.

그림 7. 마이크로서비스는 다른 여러 서비스에 API를 노출합니다.

그림 7에서 결제, 주문, 배송 마이크로서비스는 ShoppingStatus 마이크로서비스 API를 사용합니다. 데이터베이스 테이블이 서비스 중 하나와 밀접하게 관련되어 있으면 데이터를 해당 서비스로 이동하는 것이 좋습니다. 그런 다음 다른 서비스가 사용할 API를 통해 데이터를 노출할 수 있습니다. 이 구현은 서로를 자주 호출하는 세분화된 서비스가 너무 많지 않도록 도와줍니다. 서비스를 잘못 분할한 경우 서비스 경계 정의를 다시 확인해야 합니다.

분산 트랜잭션

서비스를 모놀리식에서 분리하면 원래 모놀리식 시스템의 로컬 트랜잭션이 여러 서비스에 분산될 수 있습니다. 여러 서비스에 걸쳐 있는 트랜잭션은 분산 트랜잭션으로 간주됩니다. 모놀리식 애플리케이션에서 데이터베이스 시스템은 트랜잭션이 원자적인지 확인합니다. 마이크로서비스 기반 시스템의 다양한 서비스 간 트랜잭션을 처리하려면 전역 트랜잭션 조정자를 만들어야 합니다. 트랜잭션 조정자는 이 시리즈의 다음 문서인 마이크로서비스 설정의 서비스 간 통신에 설명된 롤백, 보완 작업, 기타 트랜잭션을 처리합니다.

데이터 일관성

분산 트랜잭션에는 서비스 간 데이터 일관성을 유지해야 하는 어려움이 있습니다. 모든 업데이트는 원자적으로 수행되어야 합니다. 모놀리식 애플리케이션에서 트랜잭션 속성은 쿼리가 격리 수준에 따라 데이터베이스의 일관된 뷰를 반환하도록 보장합니다.

반면에 마이크로서비스 기반 아키텍처에서는 다단계 트랜잭션을 고려합니다. 한 서비스 트랜잭션이 실패하면 다른 서비스에서 성공한 단계를 롤백하여 데이터를 조정해야 합니다. 그렇지 않으면 애플리케이션 데이터의 전역 뷰가 서비스 간에 일관되지 않습니다.

eventual consistency를 구현하는 단계가 실패한 시기를 파악하기는 어려울 수 있습니다. 예를 들어 단계가 즉시 실패하지 않고 차단되거나 타임아웃될 수 있습니다. 따라서 일종의 타임아웃 메커니즘을 구현해야 할 수도 있습니다. 호출된 서비스에서 데이터에 액세스할 때 중복 데이터가 오래된 경우 서비스 간에 데이터를 캐싱하거나 복제하여 네트워크 지연 시간을 줄이면 데이터 일관성이 없을 수 있습니다.

이 시리즈의 다음 문서인 마이크로서비스 설정의 서비스 간 통신은 마이크로서비스 전반에서 분산 트랜잭션을 처리하는 패턴의 예시를 제공합니다.

서비스 간 통신 설계

모놀리식 애플리케이션에서 구성요소(또는 애플리케이션 모듈)는 함수 호출을 통해 직접 서로를 호출합니다. 반면에 마이크로서비스 기반 애플리케이션은 네트워크를 통해 서로 상호작용하는 여러 서비스로 구성됩니다.

서비스 간 통신을 설계할 때는 먼저 예상되는 서비스 간 상호작용 방식을 생각해야 합니다. 서비스 상호작용은 다음 중 하나일 수 있습니다.

  • 일대일 상호작용: 각 클라이언트 요청은 정확하게 하나의 서비스에 의해 처리됩니다.
  • 일대다 상호작용: 각 요청은 여러 서비스에서 처리됩니다.

또한 상호작용이 동기 또는 비동기인지 여부를 고려합니다.

  • 동기: 클라이언트가 서비스로부터 시기적절한 응답을 예상하며 기다리는 동안 차단할 수 있습니다.
  • 비동기: 클라이언트가 응답을 기다리는 동안 차단하지 않습니다. 응답이 있는 경우 즉시 전송되지는 않습니다.

다음 표는 상호작용 스타일의 조합을 보여줍니다.

일대일 일대다
동기 요청 및 응답: 서비스에 요청을 보내고 응답을 기다립니다.
비동기 알림: 서비스에 요청을 전송하되 응답이 예상되거나 전송되지 않습니다. 게시 및 구독: 클라이언트가 알림 메시지를 게시하고 0개 이상의 관심 서비스에서 메시지를 사용합니다.
요청 및 비동기 응답: 서비스에 요청을 보내면 서비스가 비동기식으로 응답합니다. 클라이언트는 차단하지 않습니다. 게시 및 비동기 응답: 클라이언트가 요청을 게시하고 관심 서비스의 응답을 기다립니다.

일반적으로 각 서비스는 이러한 상호작용 스타일의 조합을 사용합니다.

서비스 간 통신 구현

서비스 간 통신을 구현하려면 다양한 IPC 기술 중에서 선택할 수 있습니다. 예를 들어 서비스는 HTTP 기반 REST, gRPC 또는 Thrift와 같은 동기식 요청-응답 기반 통신 메커니즘을 사용할 수 있습니다. 또는 서비스에서 AMQP 또는 STOMP와 같은 비동기식 메시지 기반 통신 메커니즘을 사용할 수 있습니다. 또한 다양한 메시지 형식 중에서 선택할 수 있습니다. 예를 들어 서비스는 JSON 또는 XML과 같은 사람이 읽을 수 있는 텍스트 기반 형식을 사용할 수 있습니다. 또는 서비스는 Avro 또는 프로토콜 버퍼와 같은 바이너리 형식을 사용할 수 있습니다.

다른 서비스를 직접 호출하도록 서비스를 구성하면 서비스 간에 결합이 높아집니다. 대신 메시징 또는 이벤트 기반 통신을 사용하는 것이 좋습니다.

  • 메시징: 메시징을 구현하면 서비스가 서로 직접 호출할 필요가 없습니다. 대신 모든 서비스가 메시지 브로커를 인식하고 해당 브로커에 메시지를 푸시합니다. 메시지 브로커는 이러한 메시지를 메시지 큐에 저장합니다. 다른 서비스는 관심 있는 메시지를 구독할 수 있습니다.
  • 이벤트 기반 통신: 이벤트 기반 처리를 구현할 때 개별 서비스가 생성하는 이벤트를 통해 서비스 간 통신이 수행됩니다. 개별 서비스는 메시지 브로커에 이벤트를 작성합니다. 서비스는 관심 있는 이벤트를 리슨할 수 있습니다. 이 패턴에서는 이벤트에 페이로드가 포함되지 않으므로 서비스가 느슨하게 결합됩니다.

마이크로서비스 애플리케이션에서는 동기 통신 대신 서비스 간 비동기 통신을 사용하는 것이 좋습니다. 요청 응답은 잘 알려진 아키텍처 패턴이므로 동기 API를 설계하는 것이 비동기 시스템을 설계하는 것보다 더 자연스럽게 느껴질 수 있습니다. 메시징 또는 이벤트 기반 통신을 사용하여 서비스 간의 비동기 통신을 구현할 수 있습니다. 비동기 통신을 사용하면 다음과 같은 이점이 있습니다.

  • 느슨한 결합: 비동기 모델은 요청-응답 상호작용을 두 개의 개별 메시지로 분할합니다. 하나는 요청용이고 다른 하나는 응답용입니다. 서비스 소비자는 요청 메시지를 시작하고 응답을 기다립니다. 서비스 제공업체는 응답 메시지로 응답할 요청 메시지를 기다립니다. 이 설정은 호출자가 응답 메시지를 기다릴 필요가 없음을 의미합니다.
  • 장애 격리: 발신자는 다운스트림 소비자가 실패하더라도 메시지를 계속 보낼 수 있습니다. 소비자는 복구할 때마다 백로그를 확인합니다. 이 기능은 서비스마다 자체 수명 주기가 있기 때문에 마이크로서비스 아키텍처에서 특히 유용합니다. 그러나 동기식 API에서는 다운스트림 서비스를 사용할 수 있어야 하며 그렇지 않으면 작업이 실패합니다.
  • 응답성: 업스트림 서비스는 다운스트림 서비스에서 대기하지 않으면 더 빠르게 응답할 수 있습니다. 서비스 종속 항목의 체인이 있는 경우(서비스 A는 B를 호출하고, B는 C를 호출하는 등) 동기식 호출을 기다리면 허용되지 않는 지연 시간이 추가될 수 있습니다.
  • 흐름 제어: 메시지 큐가 버퍼 역할을 하므로 수신자가 자체 속도로 메시지를 처리할 수 있습니다.

하지만 비동기 메시징을 효과적으로 사용하기 위한 몇 가지 도전과제는 다음과 같습니다.

  • 지연 시간: 메시지 브로커에 병목 현상이 발생하면 엔드 투 엔드 지연 시간이 길어질 수 있습니다.
  • 개발 및 테스트 오버헤드: 메시징 또는 이벤트 인프라 선택에 따라 중복 메시지가 있을 수 있으므로 작업이 멱등성을 가지도록 하기 어려울 수 있습니다. 또한 비동기 메시징을 사용하여 요청-응답 시맨틱스를 구현하고 테스트하기 어려울 수 있습니다. 요청과 응답 메시지의 상관관계를 파악할 방법이 필요합니다.
  • 처리량: 중앙 큐 또는 기타 메커니즘을 사용하는 비동기 메시지 처리로 인해 시스템에 병목 현상이 발생할 수 있습니다. 큐 및 다운스트림 소비자와 같은 백엔드 시스템은 시스템의 처리량 요구사항에 맞게 확장되어야 합니다.
  • 오류 처리 복잡화: 비동기 시스템에서는 호출자가 요청의 성공 또는 실패 여부를 알 수 없으므로 오류 처리가 대역 외로 처리되어야 합니다. 이러한 유형의 시스템은 재시도 또는 지수 백오프와 같은 로직을 구현하기 어려울 수 있습니다. 모두 성공하거나 실패해야 하는 여러 연결된 비동기 호출이 있는 경우 오류 처리가 훨씬 더 복잡해집니다.

이 시리즈의 다음 문서인 마이크로서비스 설정의 서비스 간 통신은 이전 목록에서 언급된 일부 도전과제를 해결하기 위한 참조 구현을 제공합니다.

다음 단계