마이크로서비스에서 메시지 순서를 유지하며 수신자를 확장하기 위해 Kafka나 Kinesis 같은 브로커는 샤드 키(예: 주문 ID)를 사용하여 메시지를 특정 샤드에 할당하고, 각 샤드는 한 번에 하나의 컨슈머 인스턴스에만 할당되어 메시지 처리 순서를 보장합니다. 🧩
"최소 한 번 전달(at least once delivery)" 모델에서 발생하는 중복 메시지를 처리하기 위해, 비즈니스 로직을 멱등성(idempotent)으로 설계하거나, 메시지 ID를 별도의 테이블에 기록하여 이미 처리된 메시지를 식별하고 폐기하는 방법을 사용합니다. 🛡️
REST와 같은 동기식 통신은 서비스 간의 강한 결합을 유발하여 한 서비스의 장애가 전체 시스템의 가용성을 저하시키지만, 비동기 메시징은 메시지 브로커를 통해 버퍼링하여 서비스가 일시적으로 오프라인이더라도 시스템의 복원력을 높입니다. ↔️
외부 API가 즉각적인 응답을 요구하는 경우, 서비스는 다른 서비스의 이벤트를 구독하여 필요한 데이터를 로컬에 복제하거나, 클라이언트에게 즉시 응답한 후 나머지 처리를 비동기적으로 진행하여 가용성을 극대화할 수 있습니다. 🚀
데이터베이스 쓰기와 메시지 발행 간의 일관성을 보장하기 위해, "트랜잭션 아웃박스(Transactional Outbox)" 패턴을 사용하여 비즈니스 데이터 업데이트와 메시지 저장을 동일한 데이터베이스 트랜잭션 내에서 처리하고, 이후 백그라운드 퍼블리셔가 아웃박스에서 메시지를 브로커로 전송합니다. 📦