Event-Driven, Request-Response Architecture
1. 이벤트 기반(Event-Driven Architecture)
특징
서비스 간의 통신이 **이벤트(비동기 메시지)**를 통해 이루어집니다.
특정 서비스에서 이벤트를 발생시키면, 필요한 다른 서비스가 해당 이벤트를 구독하고 처리.
비동기 통신 방식을 활용하며, Pub/Sub 모델 또는 메시지 브로커(Kafka, RabbitMQ 등)를 사용.
장점
느슨한 결합:
서비스 간 직접적인 의존성이 낮음.
이벤트를 발행한 서비스는 소비자(구독자)가 누구인지 몰라도 됨.
확장성:
새로운 기능 추가 시 기존 서비스에 영향을 주지 않고 이벤트를 구독하여 확장 가능.
실시간 데이터 처리:
이벤트가 발생하는 즉시 구독자가 처리하므로 실시간 대응이 가능.
단점
복잡성 증가:
이벤트의 흐름을 관리하기 위한 추가적인 메시지 브로커나 Pub/Sub 시스템 필요.
디버깅 어려움:
이벤트가 여러 서비스 간 전파되기 때문에 전체 흐름을 추적하기 어렵다.
일관성 문제:
이벤트 소비가 비동기로 이루어지므로 데이터 일관성 유지가 어려울 수 있음.
사용 사례
Hazelcast Pub/Sub 또는 Kafka를 활용하여 이벤트 기반 통신 구현.
예: 주문 서비스가 "주문 생성" 이벤트를 발생시키고, 이를 결제 서비스와 재고 관리 서비스가 처리.
간단한 예제: 이벤트 기반 MSA
**주문 서비스(Order Service)**가 주문 생성 이벤트를 발행:
ITopic<String> topic = hazelcastInstance.getTopic("orderCreated"); topic.publish("Order #123 created");
**결제 서비스(Payment Service)**가 이벤트를 구독하여 처리:
topic.addMessageListener(message -> { System.out.println("Processing payment for: " + message.getMessageObject()); });
2. API 기반 (Request/Response)
특징
서비스 간의 통신이 REST API 또는 gRPC 같은 동기 방식으로 이루어짐.
서비스 A가 특정 작업을 위해 서비스 B의 API를 호출.
장점
직관적인 호출 방식:
요청을 보낸 서비스는 응답을 통해 작업 상태를 즉시 확인 가능.
간단한 구현:
REST API는 대부분의 언어에서 기본적으로 지원되며 설정이 간단.
데이터 일관성:
요청-응답 흐름에서 일관성을 더 쉽게 유지.
단점
높은 결합도:
서비스 A가 서비스 B의 API를 직접 호출하므로, 두 서비스 간 강한 의존성이 생김.
지연 시간:
네트워크 호출로 인해 지연 시간이 발생.
장애 전파:
호출 대상 서비스가 장애가 나면 호출자도 영향을 받을 가능성이 높음.
사용 사례
특정 작업이 요청에 따라 바로 처리되어야 하는 경우.
예: 결제 서비스가 재고 확인을 위해 상품 서비스의 API를 호출.
간단한 예제: API 기반 MSA
서비스 A가 다른 서비스의 API 호출:
RestTemplate restTemplate = new RestTemplate(); String url = "http://inventory-service/api/checkStock?productId=123"; Boolean isAvailable = restTemplate.getForObject(url, Boolean.class); System.out.println("Stock availability: " + isAvailable);
3. 이벤트 기반 vs API 기반: 선택 기준
기준 | 이벤트 기반 | API 기반 |
---|---|---|
통신 방식 | 비동기 (Pub/Sub 모델) | 동기 (요청-응답 모델) |
결합도 | 느슨한 결합 | 강한 결합 |
실시간성 | 높은 실시간 처리 (즉시 이벤트 전달) | 요청 시 즉시 응답 |
데이터 일관성 | 일관성 유지 어려움 | 비교적 쉽게 일관성 유지 |
구현 난이도 | 메시지 브로커 도입 필요, 상대적으로 복잡 | REST API로 구현 가능, 간단 |
장애 복구 및 안정성 | 한 서비스 장애 시에도 이벤트 큐에 메시지가 보존됨 | 호출 대상 서비스가 다운되면 호출 서비스도 영향을 받음 |
확장성 | 새로운 구독자 추가만으로 확장 가능 | 추가 API 호출을 구현해야 확장 가능 |
4. 현실적인 구현 방향
1) 복합 구조 (이벤트 + API 혼합)
이벤트 기반:
상태 동기화, 실시간 알림, 비동기 처리에 활용.
예: 주문 생성 시 재고 서비스, 결제 서비스에 이벤트 전파.
API 기반:
필요한 경우 특정 서비스의 데이터 또는 기능을 직접 호출.
예: 결제 서비스가 재고 확인을 위해 API 호출.
2) Hazelcast Pub/Sub을 기본으로, API를 보조로 활용
Hazelcast 클러스터 내부에서 이벤트 기반 통신(Hazelcast Pub/Sub)을 활용하여 MSA의 느슨한 결합을 유지.
클러스터 외부 서비스 또는 외부 클라이언트와 통신할 때는 REST API를 활용.
5. 결론
이벤트 기반은 느슨한 결합과 실시간 처리에 강점이 있지만, 복잡성과 디버깅 이슈가 있습니다.
API 기반은 구현이 단순하고 데이터 일관성을 유지하기 쉽지만, 서비스 간 결합도가 높습니다.
현실적으로는 이벤트 기반 + API 기반 혼합 구조를 활용하여, 상황에 따라 적절한 통신 방식을 선택하는 것이 가장 효율적입니다.