Event Broker
이벤트 브로커는 이벤트 기반 아키텍처에서 이벤트 발행자 (Producer) 와 구독자 (Consumer) 사이의 이벤트 메시지 흐름을 중개하는 미들웨어이다.
분산 마이크로서비스 환경에서 데이터 흐름의 실시간성, 비동기성, 확장성을 확보할 수 있도록 지원한다. 대용량 실시간 데이터 처리와 시스템 간의 결합도 감소, 장애 격리 및 이벤트 아카이빙 등 다양한 장점으로 인해 오늘날 IT 인프라에서 매우 중요한 역할을 차지한다.
이벤트 브로커는 Pub/Sub, 스트리밍, 다양한 QoS, 보안, 트랜잭션, 확장성, 장애 복구 등 다양한 기능을 제공하며, 시스템 간 결합도를 낮추고, 실시간 데이터 분배와 비동기 처리를 지원한다.
대표 솔루션으로는 Solace, Kafka, AWS EventBridge, Azure Event Grid 등이 있으며, 다양한 산업에서 실시간 분석, 알림, IoT, 마이크로서비스 통합 등 광범위하게 활용된다.
배경
Event Broker 는 다음과 같은 기술적 요구사항과 발전 과정을 통해 등장했다:
분산 시스템의 복잡성 증가
- 마이크로서비스 아키텍처의 확산
- 시스템 간 상호 의존성 증가
- 동기식 통신의 한계 극복 필요성
실시간 데이터 처리 요구 증가
- IoT 디바이스의 폭발적 증가
- 실시간 분석 및 대응 시스템 구축 필요
- 스트리밍 데이터 처리 패러다임 변화
기존 메시지 브로커의 한계
- 지점 간 통신 중심의 설계
- 메시지 지속성과 재처리 어려움
- 확장성과 처리량의 제약
목적 및 필요성
시스템 분리 (Decoupling)
- 이벤트 생산자와 소비자의 완전한 분리
- 시간적, 공간적 분리를 통한 유연성 확보
- 의존성 최소화로 독립적인 개발 및 배포 가능
확장성 향상 (Scalability)
- 수평적 확장을 통한 처리 능력 증대
- 동적 확장 및 축소 지원
- 워크로드 분산을 통한 효율성 개선
내결함성 보장 (Fault Tolerance)
- 시스템 일부 장애가 전체에 미치는 영향 최소화
- 자동 복구 및 재시도 메커니즘
- 데이터 손실 방지를 위한 지속성 보장
실시간 반응성 (Real-time Responsiveness)
- 이벤트 발생 즉시 관련 시스템들의 반응
- 배치 처리 대비 현저한 지연시간 단축
- 동적 비즈니스 요구사항에 신속한 대응
핵심 개념
Event Broker는 이벤트를 발행 (Publish) 하는 서비스와 이를 구독 (Subscribe) 하는 소비자 사이에서 중계자 역할을 하는 시스템 구성 요소다.
기본 개념
이벤트 (Event)
- 시스템에서 발생하는 상태 변화를 나타내는 메시지
- 불변성 (Immutable) 특성을 가지며 과거에 발생한 사실을 기록
- 이벤트 헤더 (메타데이터) 와 이벤트 페이로드 (실제 데이터) 로 구성
발행 - 구독 패턴 (Publish-Subscribe Pattern)
- 이벤트 발행자 (Publisher) 와 구독자 (Subscriber) 간의 비동기 통신 모델
- 발행자는 구독자의 존재를 알 필요가 없는 완전한 분리
- 토픽 (Topic) 기반의 이벤트 분류 및 라우팅
토픽 (Topic)
- 이벤트를 분류하고 라우팅하는 논리적 채널
- 계층적 구조를 통한 효율적인 이벤트 관리
- 와일드카드를 활용한 구독 패턴 지원
이벤트 스트림 (Event Stream)
- 시간 순서로 정렬된 이벤트들의 연속된 흐름
- 내구성과 재처리 가능성을 제공
- 실시간 및 배치 처리 모두 지원
실무 구현을 위한 핵심 연관성
확장성 측면:
- 수평적 확장을 통한 처리량 증대
- 파티셔닝을 통한 병렬 처리 지원
- 로드 밸런싱과 백프레셔 관리
신뢰성 측면:
- 이벤트 지속성과 복제를 통한 데이터 안정성
- 정확히 한 번 처리 (Exactly-once processing) 보장
- 장애 복구 및 재시작 메커니즘
성능 측면:
- 비동기 처리를 통한 응답성 향상
- 배치 처리와 압축을 통한 효율성 개선
- 메모리 및 디스크 최적화
주요 기능 및 역할
Event Broker 는 다음과 같은 핵심 기능들을 수행한다:
이벤트 수집 및 수신 (Event Ingestion)
- 다양한 소스로부터 이벤트 수집
- 이벤트 검증 및 스키마 확인
- 처리량 조절 및 백프레셔 관리
이벤트 라우팅 및 분배 (Event Routing & Distribution)
- 토픽 기반의 이벤트 분류
- 구독 패턴에 따른 선택적 배포
- 다중 소비자 지원
이벤트 지속성 (Event Persistence)
- 내구성 있는 이벤트 저장
- 복제를 통한 데이터 안정성
- 히스토리 데이터 관리
이벤트 순서 보장 (Event Ordering)
- 파티션 내 순서 보장
- 글로벌 순서 제어 옵션
- 타임스탬프 기반 정렬
특징
비동기 통신 (Asynchronous Communication)
- 논블로킹 이벤트 전송
- 생산자와 소비자의 독립적 처리
- 시스템 응답성 향상
높은 처리량 (High Throughput)
- 대용량 이벤트 스트림 처리
- 배치 처리 및 압축 최적화
- 병렬 처리 지원
내결함성 (Fault Tolerance)
- 자동 장애 감지 및 복구
- 다중 복제본 관리
- 네트워크 파티션 내성
확장성 (Scalability)
- 수평적 확장 지원
- 동적 파티션 관리
- 로드 밸런싱
핵심 원칙
이벤트 불변성 (Event Immutability)
- 한 번 기록된 이벤트는 변경되지 않음
- 히스토리 추적 및 감사 가능
- 데이터 일관성 보장
최소한의 브로커 (Dumb Broker, Smart Client)
- 브로커는 단순한 전달 역할에 집중
- 클라이언트가 복잡한 로직 처리
- 성능과 확장성 최적화
토픽 기반 라우팅 (Topic-based Routing)
- 논리적 채널을 통한 이벤트 분류
- 계층적 토픽 구조 지원
- 와일드카드 구독 패턴
주요 원리 및 작동 방식
다음은 Event Broker 의 핵심 작동 원리를 보여주는 다이어그램입니다:
graph TB subgraph "Event Producers" P1[Producer 1<br/>Web Application] P2[Producer 2<br/>Mobile App] P3[Producer 3<br/>IoT Sensor] end subgraph "Event Broker Cluster" EB1[Event Broker 1<br/>Partition A] EB2[Event Broker 2<br/>Partition B] EB3[Event Broker 3<br/>Partition C] EB1 -.->|Replication| EB2 EB2 -.->|Replication| EB3 EB3 -.->|Replication| EB1 end subgraph "Topics" T1[user.events] T2[order.events] T3[sensor.data] end subgraph "Event Consumers" C1[Consumer 1<br/>Analytics Service] C2[Consumer 2<br/>Notification Service] C3[Consumer 3<br/>Inventory Service] C4[Consumer 4<br/>ML Pipeline] end P1 -->|Publish| EB1 P2 -->|Publish| EB2 P3 -->|Publish| EB3 EB1 --> T1 EB2 --> T2 EB3 --> T3 T1 -->|Subscribe| C1 T1 -->|Subscribe| C2 T2 -->|Subscribe| C3 T3 -->|Subscribe| C4 style EB1 fill:#f9f,stroke:#333,stroke-width:2px style EB2 fill:#f9f,stroke:#333,stroke-width:2px style EB3 fill:#f9f,stroke:#333,stroke-width:2px
작동 원리 설명:
- 이벤트 발행: 프로듀서들이 다양한 토픽으로 이벤트를 발행
- 파티셔닝: 이벤트가 파티션별로 분산 저장
- 복제: 내결함성을 위한 데이터 복제
- 구독 및 소비: 컨슈머들이 관심 있는 토픽을 구독하여 이벤트 소비
구조 및 아키텍처
graph TB subgraph "Client Layer" PC[Producer Clients] CC[Consumer Clients] end subgraph "Event Broker Infrastructure" subgraph "Broker Cluster" B1[Broker Node 1] B2[Broker Node 2] B3[Broker Node 3] end subgraph "Storage Layer" S1[Segment 1] S2[Segment 2] S3[Segment 3] end subgraph "Coordination Service" ZK[ZooKeeper/Raft<br/>Metadata Management] end end subgraph "Monitoring & Management" M1[Metrics Collection] M2[Health Monitoring] M3[Configuration Management] end PC -.->|Produce Events| B1 PC -.->|Produce Events| B2 PC -.->|Produce Events| B3 B1 -.->|Consume Events| CC B2 -.->|Consume Events| CC B3 -.->|Consume Events| CC B1 <--> S1 B2 <--> S2 B3 <--> S3 B1 <--> ZK B2 <--> ZK B3 <--> ZK B1 --> M1 B2 --> M2 B3 --> M3
구성요소
구분 | 구성요소 | 기능 | 역할 | 특징 |
---|---|---|---|---|
필수 | 브로커 노드 (Broker Nodes) | 이벤트 수신, 저장, 배포 | 클라이언트 요청 처리 및 데이터 흐름 관리 | 상태 비저장 설계, 수평 확장성 뛰어남 |
스토리지 레이어 (Storage Layer) | 이벤트의 영구 저장 및 복제 | 데이터의 내구성 및 일관성 보장 | 로그 기반 저장 또는 분산 파일 시스템 활용 | |
메타데이터 관리자 (Metadata Manager) | 토픽, 파티션, 브로커 정보 관리 | 클러스터 상태 유지 및 리더 선출 | 분산 합의 알고리즘 (Raft, Zookeeper 등) 활용 | |
클라이언트 라이브러리 (Client Libraries) | 프로듀서/컨슈머 API 제공 | 이벤트 송수신, 네트워크 통신 처리 | 다양한 언어 지원, 직렬화/역직렬화 포함 | |
선택 | 스키마 레지스트리 (Schema Registry) | 이벤트 스키마 관리 및 검증 | 데이터 호환성 유지 및 스키마 진화 관리 | Avro, Protobuf 등과 연계, 중앙 집중 스키마 관리 |
커넥터 (Connectors) | 외부 시스템과의 연결 (입출력) | DB, MQ, 파일 등 외부 소스/싱크 연동 | 플러그인 기반 확장, Kafka Connect 등에서 활용 | |
스트림 프로세싱 엔진 (Stream Processing Engine) | 실시간 이벤트 변환 및 집계 | 복잡 이벤트 처리 (CEP), 데이터 파이프라인 구성 | 상태 기반 처리, 타임 윈도우, join, 필터링 등 지원 | |
모니터링 시스템 (Monitoring System) | 성능 지표 수집 및 시각화 | 시스템 운영 상태 추적 및 이상 탐지 | Prometheus, Grafana, Alertmanager 등 연계 가능 |
구현 기법
카테고리 | 구현 기법 | 정의 / 구성 요소 | 주요 목적 | 실제 예시 시스템 / 시나리오 |
---|---|---|---|---|
1. 메시징 모델 | Pub/Sub 모델 | Publisher, Subscriber, Topic 구조 | 느슨한 결합, 1:N 메시지 분배, 실시간 알림 | Kafka, Pulsar, SNS, EventBridge |
Queue 기반 모델 | Queue, Consumer, Acknowledge | 순차적 소비, 1:1 메시지 처리, 작업 큐 | RabbitMQ, Amazon SQS | |
Topic 기반 분류 | Topic, 파티션 키, Subscription Rule | 논리적 구분, 멀티 이벤트 처리, 토픽 기반 라우팅 | Kafka Topics: order.created 등 | |
2. 저장 구조 | 로그 기반 스토리지 | Append-only log, Segment, Offset, Index | 고성능 순차적 저장, 이벤트 보존 | Kafka log, Redpanda, EventStoreDB |
이벤트 소싱 | 모든 변경 이벤트 기록, 상태 재구성 | 감사/추적, 데이터 복구 및 리플레이 | Kafka + Snapshot 기반 시스템 | |
3. 데이터 처리 방식 | 스트림 처리 | Continuous ingestion, Time window, State Management | 실시간 분석, CEP, 복잡 이벤트 흐름 처리 | Flink, Kafka Streams, Spark Streaming |
Event Filtering / Routing | Rule-based 조건 필터링, 이벤트 패턴 매칭 | 조건별 라우팅, 멀티 서비스 이벤트 전달 최적화 | AWS EventBridge Rule, Solace | |
4. 확장성 및 병렬성 | 파티셔닝 (Partitioning) | Partition Key, Hashing, Leader-Follower 구조 | 병렬 처리, 확장성 확보, 소비자 그룹 분산 처리 | Kafka 파티션 설계 (user_id 기반) |
5. 신뢰성과 복원력 | 복제 (Replication) | 리더 - 팔로워, ISR, 동기/비동기 복제 | 내결함성, 데이터 유실 방지, 고가용성 | Kafka replication factor = 3 |
QoS / Delivery Guarantee | At-most/At-least/Exactly-once 설정 | 중복 방지, 메시지 손실 방지 | Kafka Idempotent Producer, SQS 설정 | |
6. 시스템 안정성 | 백프레셔 관리 | 버퍼링, 쓰로틀링, 배치 크기 조정, Flow Control | 소비자 병목 방지, 처리율 제어, 장애 확산 방지 | Kafka producer linger.ms, 쓰로틀링 정책 |
7. 인터페이스 / 통합 | 서버리스 연동 | Event → Function Trigger (Lambda/FaaS) | 비용 최적화, 온디맨드 처리, 코드 간소화 | AWS EventBridge + Lambda |
커넥터 (Connectors) | Source/Sink 플러그인, 외부 시스템 연동 | DB, MQ, 파일 시스템 통합 자동화 | Kafka Connect, Debezium | |
8. 메시지 구조 관리 | 스키마 레지스트리 | Avro/Protobuf 스키마 등록 및 검증 | 스키마 호환성, 데이터 정합성 유지, 포맷 진화 관리 | Confluent Schema Registry |
장점
카테고리 | 장점 항목 | 설명 |
---|---|---|
1. 아키텍처 유연성 | 시스템 분리 및 느슨한 결합 | Pub/Sub 모델을 통해 Producer 와 Consumer 간 직접 연결 없이 독립적으로 개발·배포 가능 |
유연한 통합 구조 | 마이크로서비스, 서버리스, 이벤트 기반 워크플로우에 자연스럽게 통합 가능 | |
2. 확장성과 성능 | 수평 확장성 | 파티셔닝과 소비자 그룹을 활용한 병렬 처리 가능, 처리량 증가 시 노드 추가만으로 선형 확장 가능 |
고성능 실시간 처리 | 이벤트 발생 직후 소비자에게 비동기 전달되어 밀리초 단위 반응 가능 | |
3. 신뢰성 및 복원력 | 내결함성 (Fault Tolerance) | 복제 및 분산 구조를 통해 단일 장애점 제거, 장애 발생 시 자동 복구 가능 |
장애 격리성 | 개별 Consumer 장애가 전체 시스템에 영향을 주지 않음 (Fail-safe 구조) | |
4. 데이터 재사용성 | 이벤트 재처리 가능 | 로그 기반 저장을 통해 과거 이벤트 재소비 가능, A/B 테스트·ML 재훈련·재처리 가능 |
감사 및 추적 용이성 | 이벤트 로그가 감사 기록으로 활용 가능, 보안/회계/컴플라이언스 측면에서 유용 | |
5. 플랫폼 호환성 | 이기종 시스템 통합 | 다양한 언어/OS/프로토콜 지원으로 이기종 플랫폼 간 통합이 용이함 |
표준 인터페이스 지원 | Kafka, MQTT, AMQP, HTTP 등 다양한 표준 프로토콜 지원 | |
6. 개발 생산성 | 비동기 이벤트 흐름 설계 용이 | 도메인 중심 이벤트 설계로 비즈니스 로직 분리, 개발 속도 및 테스트 용이성 증가 |
단점과 문제점 그리고 해결방안
단점
항목 | 설명 | 해결방안 |
---|---|---|
복잡성 증가 | 분산 시스템의 구조/운영/디버깅 난이도 증가 | 자동화된 모니터링 도구 도입 (Prometheus, Grafana), 표준 운영 가이드 수립, 통합 관제 적용 |
이벤트 흐름 추적 어려움 | 이벤트가 브로커를 거쳐 다수 소비자에게 비동기 전달되므로 호출 흐름 추적 어려움 | 분산 트레이싱 도입 (OpenTelemetry, Zipkin, Jaeger 등) |
테스트 복잡성 | 비동기 흐름/멀티 소비자 구조로 인해 E2E 테스트 난이도 ↑ | Consumer-driven contract test 도입, 테스트 환경에서 모킹 처리 |
순서 보장 제약 | 멀티 파티션 또는 다중 노드 분산 구조로 인해 글로벌 순서 보장 어려움 | 파티션 키 고정, 동일 파티션 내 메시지 처리 또는 메시지 순서 보정 로직 추가 |
지연 가능성 | 비동기 전파, 네트워크 병목, 소비자 지연 등으로 실시간성 저하 | 워커 증설, Backpressure 제어, 파티션 분산 튜닝, 적절한 batch 설정 |
비용 증가 | 메시지 로그 저장, 고가용성 구성, 멀티 AZ 구성 등으로 인해 인프라 비용 증가 | 스토리지 압축, Retention 정책 설정, 적절한 파티션/리소스 할당 |
스키마 진화 어려움 | 이벤트 구조 변경 시 하위 호환성 문제가 발생 가능 | Schema Registry 도입, backward-compatible 설계, 버전 관리 정책 수립 |
문제점
항목 | 원인 | 영향 | 탐지 및 진단 | 예방 방법 | 해결 방법 및 기법 |
---|---|---|---|---|---|
메시지 손실 | 브로커 장애, ACK 누락, 재시도 미구현 | 기능 누락, 데이터 정합성 훼손 | 메시지 카운트, 로그 분석 | 복제, Durable Storage, 멀티 AZ 구성 | ACK 기반 처리, DLQ 구성, 메시지 재전송 로직 적용 |
순서 불일치 | 멀티 파티션 또는 브로커 간 분산 처리 | 상태 불일치, 이벤트 순서 오류 | 파티션별 로그, 순서 체크 | 동일 파티션 키 지정, 순서 보장 전략 수립 | 정렬 로직 적용, 단일 파티션 구성 또는 메시지 재정렬 |
이벤트 중복 | 재전송, 리플레이 시 중복 처리 발생 가능 | 데이터 중복, 트리거 중복 수행 | 중복 카운터, ID 추적 | 멱등성 키 (Idempotent ID) 도입 | 중복 제거 로직 구현, 상태 기반 메시지 필터링 |
처리 지연 | 소비자 처리 속도 저하, 병목 발생 | 실시간 처리 실패, SLA 미준수 | TPS/Lag 모니터링, 지연 알림 | 병렬 컨슈머 증설, 네트워크 최적화 | Auto-scaling, Queue 병렬 처리, 리밸런싱 적용 |
파티션 핫스팟 | 특정 파티션으로 키가 집중되어 부하 편중 | 파티션 과부하, 병목 발생 | 파티션별 메시지 처리량 분석 | 해시 기반 분산 키 전략, 키 재설계 | 파티션 수 증가, 샤딩 적용, 키 분산 재조정 |
데이터 유실 | 저장소 고장, ACK 누락, 버퍼 유실 등 | 중요 이벤트 소실 | 로그, 모니터링, Lag 확인 | Replication, 장애 감지 자동화 | 재시도, 메시지 영속화, 장애 감지 후 자동 복구 |
도전 과제
카테고리 | 주요 이슈 (도전 과제) | 원인 또는 상황 | 영향 또는 리스크 | 해결 및 대응 전략 |
---|---|---|---|---|
확장성/성능 | 대규모 트래픽 및 이벤트 증가 | 데이터 폭증, 소비자 증가, 불균형 파티션 | 처리 지연, 처리 실패, 브로커 과부하 | 자동 스케일링, 파티셔닝 키 설계, Backpressure 제어, 멀티 브로커 구성 |
일관성/순서 | 이벤트 순서 보장/정합성 유지 어려움 | 분산 환경의 병렬 처리, CAP 제약 | 상태 기반 처리 오류, 정합성 훼손 | 파티션 키 기반 순서 관리, Outbox 패턴, CDC 연동, SAGA/보상 트랜잭션 설계 |
운영 복잡성 | 다수 컴포넌트 간의 의존성과 복잡한 트레이싱 | Pub/Sub 기반 구조, 호출 체인 없음 | 장애 원인 파악 지연, 운영 비용 증가 | OpenTelemetry, 분산 트레이싱 도입, 통합 모니터링 대시보드 구축, GitOps 기반 운영 자동화 |
신뢰성/내구성 | 메시지 유실 및 중복 처리 위험 | 네트워크 장애, 브로커 장애, ACK 실패 | 데이터 불일치, 시스템 신뢰도 하락 | 메시지 리텐션 설정, DLQ(Dead Letter Queue), 중복 제거 처리 (Idempotency) |
보안/규정 | 민감 정보 노출 및 무단 접근 가능성 | 멀티 브로커, 네트워크 기반 전송, 인증 미비 | 데이터 유출, 법적 이슈 발생 | 종단간 암호화 (TLS), 인증·인가 적용, RBAC 정책, GDPR/ISMS 등 컴플라이언스 대응 |
표준화/호환성 | 메시지 포맷 불일치 및 Schema 충돌 | Producer 간 형식 다양성, 사전 합의 부재 | Consumer 오류, 이벤트 파싱 실패 | Schema Registry 도입 (e.g., Avro, Protobuf), 계약 기반 개발 (Contract-First) 적용 |
비용/최적화 | 과도한 이벤트 발행 및 무분별한 트리거링 | 잘못된 트리거 설계, 이벤트 필터 부재 | 처리 비용 증가, 리소스 낭비 | 필터링/샘플링 적용, Rate Limit 설정, 불필요 이벤트 차단 전략 (Pre-filter, Rule 기반 조건 설계 등) |
데이터 연계성 | 관계형 DB 와 이벤트 연계 시 정합성 유지 어려움 | 트랜잭션과 이벤트 발행의 시간 차, 원자성 미보장 | 데이터 정합성 훼손, 장애 시 복구 복잡화 | Outbox Pattern, Transactional Outbox + Polling Publisher, Eventual Consistency 설계 적용 |
분류 기준에 따른 종류 및 유형
분류 기준 | 유형 | 설명 | 대표 기술/예시 |
---|---|---|---|
1. 배포 방식 | 온프레미스 (On-premise) | 조직 내 자체 인프라에서 직접 설치/운영 | Apache Kafka, RabbitMQ, NATS |
클라우드 관리형 (Managed Service) | CSP 가 운영하며 확장성/가용성 자동 제공 | AWS EventBridge, Azure Event Grid, GCP Pub/Sub | |
하이브리드 | 온프레미스와 클라우드의 통합 운영 | Confluent Platform | |
2. 처리 모델 | Pull 기반 | 소비자가 직접 메시지를 가져감 (polling) | Kafka Consumer, SQS |
Push 기반 | 브로커가 컨슈머로 직접 메시지 전달 | EventBridge → Lambda | |
3. 메시지 전달 보장 (QoS) | At-most-once | 최대 1 회 전달, 유실 가능성 있음 | 빠른 처리 우선 시 사용 |
At-least-once | 중복 허용, 데이터 손실 없음 | Kafka 기본 동작, RabbitMQ | |
Exactly-once | 정확히 한 번 처리, 높은 복잡도 | Kafka Transactions | |
4. 메시징 패턴 | Point-to-Point | 1:1 통신, 작업 큐 모델 | RabbitMQ Queue |
Publish-Subscribe | 1:N 통신, 구독자 모두에게 메시지 전달 | Kafka, MQTT | |
Request-Reply | 요청 후 응답 패턴, RPC 스타일 | gRPC over Kafka, ZeroMQ | |
5. 아키텍처 구조 | 중앙 집중형 (Centralized) | 단일 브로커 인스턴스/클러스터로 구성 | RabbitMQ 단일 노드 |
분산형 (Distributed) | 여러 노드로 구성된 클러스터 | Kafka, Pulsar | |
메시 아키텍처 (Mesh) | 브로커 간 직접 통신, 분산 라우팅 | NATS, Solace, Kafka MirrorMaker | |
6. 저장 방식 | In-memory | 메시지를 메모리에만 저장, 휘발성 | Redis PubSub |
Disk-based | 디스크에 영속 저장, 재처리 가능 | Kafka, RabbitMQ | |
하이브리드 | 메모리와 디스크 혼합 전략 | Apache Pulsar | |
7. 메시지 처리 유형 | 스트리밍 (Streaming) | 실시간 연속 처리 모델 | Kafka Streams, Flink |
배치 (Batch) | 일괄 처리, 주기적 트리거 | Spark Structured Streaming | |
8. 프로토콜 | AMQP | 고급 메시징 기능 지원, 표준화 | RabbitMQ, ActiveMQ |
MQTT | 경량 메시징, IoT 특화 | Mosquitto, HiveMQ | |
STOMP | 텍스트 기반 단순 프로토콜 | RabbitMQ (웹 통신용) | |
Kafka Protocol | 바이너리 TCP 기반 고성능 프로토콜 | Apache Kafka | |
9. 메시지 저장 모델 | 큐 기반 (Queue-based) | 메시지는 소비 후 삭제됨 | RabbitMQ |
로그 기반 (Log-based) | 메시지는 로그로 저장되고 다중 소비 가능 | Kafka, Pulsar | |
토픽 기반 (Topic-based) | 메시지를 주제별로 분리/전파 | Kafka, MQTT | |
10. 대표 제품 유형 | 메시지 브로커 (Message Broker) | 큐 중심 메시징, 트랜잭션 지원 | RabbitMQ, ActiveMQ |
이벤트 브로커 (Event Broker) | 이벤트 스트림, 로그 기반 처리 | Kafka, EventStoreDB | |
서비스 버스 (Service Bus) | 라우팅/변환/오케스트레이션 기능 포함 | Azure Service Bus, NServiceBus |
Event Broker 기술별 비교
항목 구분 | Apache Kafka | AWS EventBridge | Azure Event Grid | Google Cloud Eventarc |
---|---|---|---|---|
형태 | 오픈소스, 자체 호스팅 (Self-Managed) | Fully Managed (서버리스) | Fully Managed (서버리스) | Fully Managed (서버리스, Kubernetes 기반) |
아키텍처 유형 | Pull 기반 Consumer Group 구조 | Rule 기반 이벤트 라우팅 + Push | Event Subscription + HTTP Push | Event Trigger + Cloud Run 연계 |
이벤트 보존 | 디스크 기반 로그 저장 (Retention 설정 가능) | 기본 TTL 존재 (장기 저장 불가) | 기본 TTL 존재 (수분~수시간 수준) | 일시적 처리 (장기 보존 미지원) |
필터링 기능 | Consumer 애플리케이션 내부 처리 | Event Pattern 기반 JSON 필터 | 고급 필터 (속성 기반, 주제 기반 등) | 조건 필터 + 대상 서비스 조합 가능 |
성능 지표 | 수백만 TPS 이상, 고성능 스트리밍 | 수만 TPS 수준 | 수만 TPS 수준 | 수천~수만 TPS 수준 |
통합/연계성 | 외부 시스템 및 커스텀 애플리케이션과 유연한 연계 | AWS 서비스 및 SaaS 연계 최적화 | Azure 리소스 및 서드파티 연동 최적화 | GCP 서비스 (Cloud Run, Function 등) 연동 최적화 |
재처리 지원 | ✅ 오프셋 기반 재처리 (내구성 우수) | ❌ 기본 미지원 (Lambda 재시도 설정 필요) | ❌ 이벤트 재처리 구조 미제공 | ❌ Cloud Run 재실행 필요 |
활용 사례 | IoT 센서 수집, 대용량 로그 스트림 분석 | 주문 생성 → Lambda 트리거 | Azure Blob 생성 → Logic App 실행 | Firebase 등록 이벤트 → 메일 발송 |
강점 요약 | 고성능, 내구성, 재처리/순서보장/파티셔닝 지원 | AWS 서비스 간 손쉬운 통합, 간단한 서버리스 워크플로우 | 고급 필터링 및 Azure 서비스 통합 | Kubernetes 및 GCP 기반 서버리스 최적화 |
적합한 사용 시점 | 대용량 스트리밍, 재처리 필요, 멀티컨슈머 구조 | 간단한 이벤트 트리거 자동화, AWS SaaS 연동 | 리소스 이벤트 감지 및 처리 자동화 | GCP 이벤트 기반 서버리스 파이프라인 구축 |
요약
구분 | 분석 결과 요약 |
---|---|
Kafka | 자체 호스팅 기반으로 고성능 이벤트 스트리밍, 이벤트 재처리, 내구성 요구 환경에 적합. 컨슈머 그룹으로 다중 처리 가능. 복잡하지만 유연함. |
AWS EventBridge | AWS 환경에서 Lambda 등과 결합 시 매우 간단하게 이벤트 처리 가능. 서버리스와 SaaS 연동이 쉽고, 간단한 이벤트 기반 워크플로우에 최적. |
Azure Event Grid | Azure 자원 이벤트 처리에 최적화되어 있으며, 고급 필터링 및 HTTP Push 연동 기능 강력. Logic App 과의 연계 유용. |
Google Eventarc | GCP 내 Cloud Run 기반 서버리스 워크플로우 구성에 강점. Kubernetes 기반 워크플로우 또는 Firebase 등과의 연계에 특화. |
Event Broker 구축 예제
Kafka 를 사용하여 Event Broker 환경을 구축하고 간단한 Producer-Consumer 이벤트 흐름을 구현한다.
구성:
- Apache Kafka
- Python (
kafka-python
라이브러리)
설치 준비
1 2 3 4 5 6 7 8 9
# Kafka & Zookeeper 실행 (Docker 기반 예시) docker run -d --name zookeeper -p 2181:2181 zookeeper docker run -d --name kafka -p 9092:9092 \ -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \ -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT \ -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \ --network=host \ confluentinc/cp-kafka
Python Producer 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# producer.py from kafka import KafkaProducer import json producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) event = {'event_type': 'OrderCreated', 'order_id': 1234, 'user_id': 5678} producer.send('order-events', value=event) producer.flush() print("✅ OrderCreated 이벤트 전송 완료")
Python Consumer 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# consumer.py from kafka import KafkaConsumer import json consumer = KafkaConsumer( 'order-events', bootstrap_servers='localhost:9092', auto_offset_reset='earliest', group_id='order-service', value_deserializer=lambda m: json.loads(m.decode('utf-8')) ) for message in consumer: print(f"✅ 수신된 이벤트: {message.value}")
Kafka 모니터링 지표 및 실전 대시보드 구성
Tool: Prometheus + Grafana
주요 지표:
지표 | 설명 |
---|---|
kafka_server_brokertopicmetrics_messages_in_total | 초당 수신 메시지 수 |
kafka_server_brokertopicmetrics_bytes_in_total | 수신 바이트 수 |
kafka_server_brokertopicmetrics_bytes_out_total | 전송 바이트 수 |
kafka_server_replicamanager_underreplicated_partitions | 동기화 안된 파티션 수 |
kafka_network_requestmetrics_requests_total | 총 네트워크 요청 수 |
kafka_controller_kafkacontroller_activecontrollercount | 활성 컨트롤러 수 (1 이 아니면 비정상) |
kafka_log_logsize | 토픽/파티션별 로그 사이즈 |
실전 대시보드 구성
Exporter 설치
Kafka 용 JMX Exporter 사용:Prometheus 설정 예시
Grafana 대시보드 템플릿
- ID:
7589
(confluentinc 제공 Kafka Dashboard) - 대시보드 포함 항목:
- 브로커별 처리량
- 파티션 상태
- lag 상태
- consumer group health
- 메시지 지연 현황
- ID:
실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점
카테고리 | 고려사항 | 설명 | 권장사항 |
---|---|---|---|
1. 토픽/파티션 설계 | 토픽 네이밍/구조 설계 | 도메인 중심의 계층적 토픽 설계가 필요함 | 도메인.이벤트명 규칙 적용 (order.created ) |
파티션 전략 및 수량 | 병렬성 확보, 순서 보장 위한 파티션 설계 | 키 기반 파티셔닝, 예상 처리량의 2~3 배로 설정 | |
2. 메시지 일관성 | 메시지 순서 및 중복 처리 | 중복 소비/재처리 방지 및 순서 보장 필요 | 메시지 ID, 타임스탬프, 멱등 소비자 처리 |
멱등성 (Idempotency) | 중복 이벤트 수신 시 상태 변화 방지 | 상태 조회 기반 멱등 처리 또는 상태머신 적용 | |
3. 장애 복구 및 실패 처리 | 메시지 유실/지연 대응 | 브로커 장애, 소비자 실패 시 데이터 보호 | DLQ 구성, Retry 전략, Replication 적용 |
메시지 재처리 | 장애 후 재처리 위한 이벤트 보존 필요 | Kafka replay, TTL 기반 재전송 지원 | |
4. 모니터링 및 가시성 | 이벤트 흐름 추적 및 문제 진단 | 흐름 시각화 및 에러 식별 필요 | OpenTelemetry, Prometheus, Kafka UI 등 도입 |
실시간 지표 모니터링 | 처리량, 지연, 실패율 등 지표 확인 필요 | APM, 알림, 대시보드 구축 | |
5. 스키마 관리 | 이벤트 포맷 일관성 및 진화 전략 | 버전 충돌, 하위 호환성 문제 방지 필요 | Schema Registry 도입, Avro/Protobuf 적용 |
필드 변경/추가 대응 | 소비자 호환성 유지 필요 | backward-compatible 스키마 설계 | |
6. 성능 최적화 | 배치 크기/지연 시간 조절 | 처리량과 응답 속도 간 균형 조정 필요 | linger.ms , batch.size 등 튜닝 |
압축 및 캐싱 | 전송 및 저장 효율 향상 | snappy/gzip 압축, 커넥션 풀, 메타데이터 캐시 | |
7. 보안 및 접근 제어 | 인증/인가 | 메시지 접근 통제 및 식별자 관리 | IAM, JWT, SASL, ACL 설정 |
암호화 | 데이터 전송/저장 보호 | TLS/SSL 적용, 디스크 암호화 | |
감사 및 감사 로그 | 접근/변경 기록 추적 | 감사 로그 수집 및 보존 정책 설정 | |
8. 배포 및 인프라 전략 | 고가용성 구성 | 단일 장애점 제거 및 무중단 운영 | 멀티 AZ, 클러스터 구성, 자동 장애 조치 설정 |
자동 확장 | 트래픽 급증 대응 | Horizontal Pod Autoscaler, KEDA 등 사용 | |
백업 및 재해 복구 | 데이터 손실 방지 | 정기 백업 + 재해 복구 시나리오 문서화 | |
9. 용량 및 트래픽 계획 | 메시지 양/트래픽 예측 | 리소스 부족 시 병목/지연 발생 가능성 | 예측 기반 스케일링, Kafka Cruise Control 도입 |
스토리지 최적화 | 이벤트 보존 설정과 디스크 용량 균형 | 보존 기간 조절, 압축 전략, 토픽 정리 | |
10. 우선순위 및 QoS | 중요도 기반 메시지 처리 | 긴급 메시지 우선 처리 필요 | 우선순위 큐, 별도 토픽/채널로 분리 |
QoS (전달 보장 수준) | At-least-once vs Exactly-once 결정 필요 | 트랜잭션 + 멱등 프로듀서 설정 (Kafka 기준) |
아키텍처 설계 시 고려 요소
고려 항목 | 설명 | 권장 사항 |
---|---|---|
도메인 분리 | 이벤트는 업무 도메인 단위로 구성되어야 함 | order.created , payment.success 등 명확한 이벤트 명명 |
이벤트 흐름 시각화 | 전체 이벤트 흐름을 설계 초기부터 도식화 | Sequence Diagram, Event Map 활용 |
브로커 선택 | 워크로드와 운영 역량에 따라 선택 | 대규모 실시간: Kafka / 간단 자동화: EventBridge |
스키마 관리 | 이벤트 스키마는 반드시 버저닝 및 관리 필요 | Avro + Schema Registry 구성 필수 |
멱등성 처리 | 중복 이벤트에 안전한 설계 필요 | 이벤트 ID + 상태 기반 로직 설계 |
배포 전략
항목 | 전략 | 도구 |
---|---|---|
브로커 배포 | 자체 운영 또는 매니지드 | Kafka, AWS MSK, GCP Pub/Sub |
메시지 소비자 배포 | 컨테이너 또는 서버리스 함수 | Docker, Kubernetes, AWS Lambda |
토픽/구독 설정 자동화 | IaC 기반 구성 | Terraform, AWS CDK, Azure Bicep |
모니터링 연동 | 이벤트 지연/누락 추적 | Prometheus, Datadog, Kafka Lag Exporter |
보안 설정 | IAM, 인증서, 메시지 암호화 | TLS, VPC 연결, OAuth/JWT 인증 등 |
테스트 및 검증 전략
테스트 항목 | 설명 | 도구/기법 |
---|---|---|
계약 기반 테스트 | Producer 와 Consumer 간 메시지 형식 합의 | Pact, Spring Cloud Contract |
성능 테스트 | TPS, 처리 지연, 이벤트 누락 여부 검증 | JMeter, Locust, Kafka-producer-perf-test |
오류 시나리오 | 브로커 장애, 네트워크 단절, 소비자 중단 | Chaos Monkey, ToxiProxy |
재처리 시나리오 | 이벤트 리플레이가 정상 동작하는지 | Kafka Consumer Offset Reset |
보안 테스트 | 인증 미비, 권한 우회 등 검증 | IAM Role 테스트, 토픽 접근 제어 테스트 |
운영 자동화 및 모니터링
운영 항목
항목 | 모니터링 지표 | 도구 |
---|---|---|
브로커 상태 | CPU, Disk I/O, Partition Lag | Prometheus + Grafana |
이벤트 처리 지연 | Consumer Lag, 처리 시간 | Kafka Lag Exporter |
이벤트 유실/중복 | 전송 실패율, DLQ 비율 | AWS CloudWatch, Elastic |
보안 감사 | 접근 로그, 인증 실패 로그 | CloudTrail, Kafka Audit Logs |
스키마 변경 추적 | Schema version 변경, Incompatibility 감지 | Confluent Schema Registry, diff 도구 |
자동화 요소
자동화 영역 | 방법 |
---|---|
토픽 생성/관리 | IaC (Terraform, CDK) |
알림 설정 | Slack, PagerDuty 연동 |
소비자 배포 파이프라인 | GitOps, ArgoCD, GitHub Actions |
리플레이 트리거 | Kafka CLI, Lambda 트리거 구성 |
소비자 헬스체크 | Kubernetes liveness/readiness probes |
최적화하기 위한 고려사항 및 주의할 점
카테고리 | 고려사항 | 설명 | 권장사항 |
---|---|---|---|
1. 메시지 처리 최적화 | 메시지 크기 제한 | 메시지가 너무 크면 브로커, 네트워크에 부하 발생 | 메시지 크기 제한 설정 (ex: 1~10MB), 대용량은 외부 저장소 활용, 압축 적용 |
배치 처리 | 개별 메시지 전송은 오버헤드 큼 | linger.ms , batch.size 최적화, Consumer Poll 조정 | |
압축 전략 | 네트워크 효율은 높이지만 CPU 부하 발생 | Snappy, ZSTD 등 적절한 알고리즘 선택 및 압축 수준 조절 | |
이벤트 경량화 | 메시지 내용 중 불필요 데이터 제거 | Avro, Protobuf 등 경량 포맷 사용 | |
2. 파티션/병렬성 설계 | 파티션 전략 | 파티션 수는 병렬성/순서 보장에 직접 영향 | 파티션 수 = 소비자 수 고려, 키 기반 파티션 전략 적용, 핫 파티션 방지 |
소비자 그룹 설계 | 잘못된 그룹 구성은 오히려 처리량 감소 | 병렬 처리 극대화를 위한 균형 잡힌 파티션 할당 | |
스레드 및 워커 설정 | 스레드/워크자 수 부족 시 처리 병목 발생 | 멀티스레드 처리 또는 비동기 워커 활용 | |
3. 네트워크/IO 최적화 | 네트워크 지연/대역폭 | 지역 간 전송, 느린 네트워크는 Latency 증가 | 브로커 - 클라이언트 근접 배치, TCP 튜닝, 전용 네트워크 고려 |
디스크 I/O | 디스크 쓰기 지연은 메시지 저장 지연으로 직결 | SSD 사용, 로그 세그먼트 최적화, I/O 스레드 분리 | |
캐싱 전략 | 반복 요청/메타데이터 접근 비용 발생 | 클라이언트 메타데이터 캐싱, 캐시 무효화 정책 수립 | |
4. 리소스 관리 및 인프라 | CPU / 메모리 | JVM, 네이티브 메모리 부족 시 GC, 성능 저하 유발 | JVM 튜닝, 힙/버퍼 설정 최적화, 컨테이너 리소스 설정 조정 |
오토스케일링 | 고정 노드는 트래픽 급증에 대응 어려움 | KEDA, AutoScalingGroup 등 자동 확장 구성 | |
Broker 설정 | 기본 설정이 워크로드에 부적합할 수 있음 | 브로커당 처리량, 큐 크기, 내부 버퍼 최적화 | |
5. 장애 복구/안정성 | 복제 전략 | 복제는 장애 복구에 중요하지만 과도하면 성능 저하 | 비동기 복제 활용, 적절한 ISR(In-Sync Replica) 수 설정 |
DLQ 구성 | 장애 메시지 처리 실패 시 무한 루프/손실 발생 위험 | Dead Letter Queue 활용, 재시도 정책 적용 | |
백프레셔 | 과부하 시 시스템 전체 성능 저하 | Throttling, Circuit Breaker 패턴 도입 | |
6. 운영 및 모니터링 | 모니터링 오버헤드 | 과도한 지표 수집은 처리 흐름에 부정적 영향 | 샘플링 적용, 핵심 지표만 수집, Prometheus, Datadog 활용 |
성능 지표 추적 | Throughput, Latency, Lag 등 실시간 분석 필요 | Grafana + Prometheus + Alertmanager 등 연계 | |
장애 탐지/알림 | 장애 발생 시 빠른 대응 필수 | 자동화된 장애 감지 및 알림 시스템 구축 (예: AIOps 연동) | |
7. 보존 및 데이터 정책 | 메시지 보존 | 메시지를 너무 오래 저장하면 스토리지 비용 증가 | 주기적 만료 설정, Retention 정책 정의, 히스토리 백업 |
스토리지 관리 | 로그 누적이 디스크 병목을 유발할 수 있음 | 계층형 스토리지 구성 (hot/cold), 메시지 압축 활성화 |
실무 사용 예시
📌 적용 분야 | 대표 시나리오 | 사용 기술 | 주요 효과 |
---|---|---|---|
1. 전자상거래 / 주문 처리 | 주문 이벤트 기반 멀티 서비스 처리 (결제, 재고, 배송 등) | Kafka, RabbitMQ, SQS, Spring Boot, MongoDB | 주문 워크플로우 비동기 처리, 확장성 확보 |
2. 실시간 알림 서비스 | 사용자 활동 (댓글, 좋아요 등) 에 대한 실시간 알림 | Kafka, Redis PubSub, Solace, AWS SNS | 실시간 반응형 UX, 빠른 알림 분배 |
3. IoT / 센서 네트워크 | 대규모 센서 데이터의 실시간 수집 및 처리 | MQTT, Kafka, Google Eventarc, InfluxDB, Grafana | 고빈도 이벤트 처리, 실시간 모니터링 |
4. 데이터 파이프라인 / 분석 | 데이터 이벤트 기반 스트리밍 처리 및 ELT 파이프라인 구성 | Kafka Connect, Apache Flink, EventBridge, ELK, BigQuery | 대용량 실시간 분석, ETL 자동화 |
5. 금융 / 거래 추적 | 실시간 결제 흐름, 사기 탐지, 거래 분석 | Kafka, Flink, Elasticsearch, Apache Pulsar | 트랜잭션 추적, 이상 탐지, 실시간 정합성 |
6. 마이크로서비스 통합 | 서비스 간 느슨한 결합 기반 비동기 이벤트 통신 | Kafka, RabbitMQ, Azure Event Grid, Docker, Istio | 독립적 배포, 서비스 확장 유연성 |
7. 로그 수집 및 모니터링 | 마이크로서비스의 로그/메트릭을 중앙 시스템으로 전송 | Kafka, Fluentd, OpenTelemetry, Prometheus, Grafana | 시스템 상태 가시성 향상, 장애 대응 |
8. 서버리스 자동화 | 클라우드 리소스 변경, 예약 이벤트에 따른 Lambda 트리거 실행 | AWS EventBridge + Lambda, Azure Functions, GCP Eventarc | 인프라 자동화, 코드 간소화 |
9. 실시간 사용자 추적 | 사용자의 웹/앱 활동 실시간 분석 및 추천 시스템 연결 | Azure Event Hub, Kafka, Apache Spark, Snowflake Streams | 행동 분석 기반 실시간 추천 강화 |
활용 사례
사례 1: IoT 센서 로그와 웹 서버 로그를 실시간으로 수집·분석
시스템 구성도
flowchart LR IoT[IoT/웹서버] --> Broker[Event Broker] Broker --> Analyzer[Log Analyzer/Consumer] Broker --> Storage[Raw Log 저장소] Analyzer --> BI[DashBoard/Alert]
Workflow
- IoT/웹서버에서 로그 이벤트 발생 → 브로커로 발행
- 브로커가 Analyzer(실시간 처리) 및 Storage(저장) 에 동시에 브로드캐스트
- Analyzer 는 실시간 알림 또는 대시보드에 결과 전달
주제의 역할: 서로 다른 데이터 소스를 빠짐 없이 실시간 브로드캐스팅, 대용량 처리, 장애 시 재처리 가능
유무 차이: 이벤트 브로커 없을 시, 다수 대상 동시 전달 힘들고 확장/유지보수 취약, 장애 전파 쉬움
구현 예시:
|
|
- Producer 는 ’log-events’ 토픽에 메시지를 보내고, Consumer 는 같은 토픽을 구독하여 메시지를 실시간으로 소비/처리
사례 2: 이커머스 주문 시스템에서의 Event Broker 활용
시스템 구성:
- Producer: 주문 마이크로서비스
- Broker: Apache Kafka
- Consumer:
- 재고 시스템
- 배송 시스템
- 알림 서비스
- 이벤트 로깅 (ELK)
flowchart TD A[Order Service] --> B[Kafka Topic: order.created] B --> C[Inventory Service] B --> D[Shipping Service] B --> E[Notification Service] B --> F[Analytics Dashboard]
Workflow:
order.created
이벤트가 Kafka 에 발행됨- Kafka 는 이를 다수 Consumer 에 브로드캐스트
- 각 Consumer 는 독립적으로 이벤트를 처리 (예: 배송 트리거, 알림 전송, 재고 차감)
역할 분석:
- Event Broker는 Producer-Consumer 간 결합을 제거
- 복수 시스템에서 동시에 이벤트 소비 가능
- Kafka 는 이벤트 로그를 유지하여 리플레이/장애 복구도 지원
유무 비교:
항목 | Event Broker 사용 | 미사용 시 |
---|---|---|
이벤트 분기 | 다수 시스템 자동 처리 | 명시적 코드로 분기 필요 |
장애 대응 | 개별 서비스 영향 없음 | 동기 호출 시 전체 실패 가능성 |
확장성 | 새로운 소비자 즉시 추가 가능 | 기존 서비스 코드 수정 필요 |
구현 예시:
|
|
|
|
사례 3: 글로벌 전자상거래 플랫폼의 실시간 주문 처리
대형 전자상거래 플랫폼에서 Event Broker 를 활용하여 주문부터 배송까지의 전체 워크플로우를 실시간으로 처리하는 시스템을 구축한 사례.
시스템 구성
graph TB subgraph "Frontend Layer" WEB[Web Application] MOBILE[Mobile App] API[API Gateway] end subgraph "Event Broker Infrastructure" KAFKA[Apache Kafka Cluster] end subgraph "Microservices" ORDER[Order Service] PAYMENT[Payment Service] INVENTORY[Inventory Service] SHIPPING[Shipping Service] NOTIFICATION[Notification Service] ANALYTICS[Analytics Service] end subgraph "Data Storage" ORDERDB[(Order DB)] INVENTORYDB[(Inventory DB)] USERDB[(User DB)] CACHE[(Redis Cache)] end WEB --> API MOBILE --> API API --> ORDER ORDER --> KAFKA PAYMENT --> KAFKA INVENTORY --> KAFKA SHIPPING --> KAFKA KAFKA --> ORDER KAFKA --> PAYMENT KAFKA --> INVENTORY KAFKA --> SHIPPING KAFKA --> NOTIFICATION KAFKA --> ANALYTICS ORDER --> ORDERDB INVENTORY --> INVENTORYDB PAYMENT --> USERDB NOTIFICATION --> CACHE
워크플로우
sequenceDiagram participant Customer participant OrderService participant EventBroker participant PaymentService participant InventoryService participant ShippingService participant NotificationService Customer->>OrderService: 주문 요청 OrderService->>EventBroker: order.created 이벤트 발행 EventBroker->>PaymentService: 결제 처리 트리거 EventBroker->>InventoryService: 재고 확인 트리거 PaymentService->>EventBroker: payment.processed 이벤트 발행 InventoryService->>EventBroker: inventory.reserved 이벤트 발행 EventBroker->>ShippingService: 배송 준비 트리거 EventBroker->>NotificationService: 고객 알림 트리거 ShippingService->>EventBroker: shipping.prepared 이벤트 발행 EventBroker->>NotificationService: 배송 알림 트리거 NotificationService->>Customer: 주문 완료 알림
Event Broker 의 역할
- 실시간 이벤트 라우팅: 주문 생성 시 관련된 모든 서비스에 즉시 알림
- 비동기 처리: 각 서비스가 독립적으로 작업을 수행하여 전체 응답 시간 단축
- 장애 격리: 한 서비스의 장애가 다른 서비스에 미치는 영향 최소화
- 확장성: 트래픽 증가 시 개별 서비스 확장 가능
Event Broker 유무에 따른 차이점
- Event Broker 사용 시:
- 평균 주문 처리 시간: 2-3 초
- 시스템 간 결합도: 낮음
- 확장성: 개별 서비스 단위로 수평 확장 가능
- 장애 영향 범위: 제한적
- Event Broker 미사용 시 (동기식 API 호출):
- 평균 주문 처리 시간: 8-12 초
- 시스템 간 결합도: 높음
- 확장성: 전체 시스템 단위로만 확장 가능
- 장애 영향 범위: 연쇄적 장애 발생 가능
구현 예시:
|
|
이 구현 예시는 Event Broker 의 핵심 개념들을 실제 코드로 보여줍니다:
- 비동기 이벤트 처리:
asyncio
를 활용한 논블로킹 처리 - 토픽 기반 라우팅: 토픽별 구독자 관리
- 느슨한 결합: 서비스 간 직접 호출 없이 이벤트를 통한 통신
- 이벤트 재처리: 히스토리 기반 재처리 기능
- 에러 핸들링: 구독자별 예외 처리
사례 4: 실시간 알림 서비스
SNS, 커뮤니티, 커머스 등 거의 모든 서비스에서 사용되며, 일반적으로 Event-Driven Architecture + Pub/Sub 기반 알림 브로커 + WebSocket/Push API 조합으로 구현된다.
시스템 구성:
컴포넌트 | 역할 |
---|---|
Kafka | 이벤트 버퍼 및 브로커 역할 |
Comment Service | 이벤트 생성 및 발행 |
Notification Service | 이벤트 수신 → 알림 생성/전송 |
WebSocket Gateway | 사용자에게 실시간 알림 전달 |
Notification DB | 알림 이력 저장 (선택 사항) |
graph TD A[사용자] -->|댓글 작성| B(API Gateway) B --> C[Comment Service] C -->|Event 생성| D(Kafka Topic: comment.events) D --> E[Notification Service] E -->|WebSocket 전송| F[WebSocket Gateway] F --> G[실시간 연결 사용자] E -->|DB 저장| H[Notification DB]
Workflow:
단계 | 설명 |
---|---|
1. 사용자 댓글 작성 | 사용자가 게시글에 댓글을 작성 |
2. 이벤트 발행 | Comment Service 는 CommentCreated 이벤트를 Kafka 에 발행 |
3. 알림 서비스 수신 | Notification Service 가 해당 이벤트를 소비하고, 알림 데이터를 구성 |
4. 실시간 전송 | WebSocket 을 통해 실시간 연결된 사용자에게 즉시 알림 전송 |
5. 알림 저장 | 알림을 데이터베이스에 저장하여, 추후 알림 리스트 조회 가능 |
구현 코드:
Kafka 이벤트 발행–
Comment Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# comment_service.py from kafka import KafkaProducer import json producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) def publish_comment_event(comment_data): event = { "type": "CommentCreated", "post_id": comment_data["post_id"], "commenter_id": comment_data["user_id"], "receiver_id": comment_data["post_owner_id"], "message": comment_data["text"] } producer.send('comment.events', event) producer.flush()
Kafka 이벤트 소비 + WebSocket 연동–
Notification Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
# notification_service.py from kafka import KafkaConsumer import json from fastapi import FastAPI, WebSocket from collections import defaultdict import asyncio app = FastAPI() active_connections = defaultdict(list) # user_id -> list of WebSockets @app.websocket("/ws/{user_id}") async def websocket_endpoint(websocket: WebSocket, user_id: str): await websocket.accept() active_connections[user_id].append(websocket) try: while True: await websocket.receive_text() # Keep connection alive finally: active_connections[user_id].remove(websocket) def send_realtime_notification(user_id, message): for ws in active_connections[user_id]: asyncio.create_task(ws.send_text(message)) def run_kafka_consumer(): consumer = KafkaConsumer( 'comment.events', bootstrap_servers='localhost:9092', group_id='notification-group', value_deserializer=lambda m: json.loads(m.decode('utf-8')) ) for msg in consumer: data = msg.value receiver_id = data['receiver_id'] text = f"새 댓글이 달렸습니다: {data['message']}" send_realtime_notification(receiver_id, text) # 비동기 Kafka consumer 실행 import threading threading.Thread(target=run_kafka_consumer, daemon=True).start()
클라이언트 (WebSocket JS 예시)
사례 5: 마이크로서비스 아키텍처에서 서비스 간 통합
주문 처리 시스템
- 사용자가 주문을 생성하면
Order Service
가OrderCreated
이벤트를 발행하고,Inventory Service
와Payment Service
가 이를 구독해 각각 재고 확인과 결제 처리를 수행한다.
시스템 구성:
컴포넌트 | 역할 |
---|---|
Kafka | 서비스 간 이벤트 전달 버스 역할 |
Order Service | 주문 저장 및 OrderCreated 이벤트 발행 |
Inventory Service | 재고 확인 및 후속 이벤트 발행 |
Payment Service | 결제 처리 및 후속 이벤트 발행 |
flowchart TD A[Client] -->|POST /orders| B[Order Service] B -->|OrderCreated Event| C[Kafka Topic: order.events] C --> D[Inventory Service] C --> E[Payment Service] D -->|InventoryReserved| F[Kafka Topic: inventory.events] E -->|PaymentProcessed| G[Kafka Topic: payment.events]
Workflow:
단계 | 설명 |
---|---|
1. 주문 생성 | 사용자가 주문 요청을 보내면 Order Service 가 DB 에 주문 저장 |
2. 이벤트 발행 | 주문이 저장되면 Kafka 에 OrderCreated 이벤트 발행 |
3. 재고/결제 처리 | Inventory Service 와 Payment Service 는 이벤트를 수신해 각각 처리 |
4. 후속 이벤트 발행 | 각각 처리 결과 (InventoryReserved , PaymentProcessed ) 를 발행하여 후속 프로세스 연동 |
구현 예시:
Order Service–이벤트 발행
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# order_service.py from kafka import KafkaProducer import json from fastapi import FastAPI, Request app = FastAPI() producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) @app.post("/orders") async def create_order(req: Request): body = await req.json() order = { "order_id": body["order_id"], "user_id": body["user_id"], "items": body["items"], "total": body["total"] } # 가상 DB 저장 생략 producer.send('order.events', { "type": "OrderCreated", "data": order }) producer.flush() return {"status": "Order created and event published"}
Inventory Service–이벤트 소비자
|
|
Payment Service–이벤트 소비자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
# payment_service.py from kafka import KafkaConsumer, KafkaProducer import json consumer = KafkaConsumer( 'order.events', bootstrap_servers='localhost:9092', group_id='payment-service', value_deserializer=lambda m: json.loads(m.decode('utf-8')) ) producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) def handle_order_created(event_data): amount = event_data['data']['total'] # 결제 처리 로직 (가정) is_paid = True if is_paid: result = { "type": "PaymentProcessed", "data": { "order_id": event_data['data']['order_id'], "status": "paid" } } producer.send('payment.events', result) producer.flush() for msg in consumer: event = msg.value if event['type'] == "OrderCreated": handle_order_created(event)
주목할 내용
카테고리 | 주요 항목 | 설명 |
---|---|---|
아키텍처 패턴 | Pub/Sub | 발행자와 구독자 간의 비동기 이벤트 전달 모델 |
Event Sourcing | 상태 변경을 이벤트 시퀀스로 기록하는 패턴 | |
CQRS | 명령/조회 분리 아키텍처, 읽기/쓰기 최적화 | |
Fan-out | 하나의 이벤트를 다수의 소비자가 수신하는 패턴 | |
Event Mesh | 복수 브로커 간 메시지 전달을 지원하는 통합 네트워크 구조 | |
Event Gateway | 외부 이벤트를 브로커로 전달하는 통합 인터페이스 | |
State-centric Messaging | 분산 상태 관리와 메시징을 결합한 패러다임 | |
메시지 - 쿼리 통합 | 메시징 시스템과 데이터베이스 쿼리 기능의 결합 형태 | |
운영/관리 기술 | Schema Registry | 이벤트 메시지 포맷의 버전 관리 및 유효성 검증 도구 |
Tracing / Logging | 이벤트 흐름 및 장애 분석용 관찰 도구 (OpenTelemetry 등) | |
오토스케일링 | Kubernetes 기반 자동 확장 기능 | |
리밸런싱 / 백프레셔 | 소비자 할당 재조정 및 과부하 제어 기법 | |
Event Replay | 메시지 재처리를 위한 이벤트 로그 재생 기능 | |
통합 가시성 도구 | 멀티 브로커/환경 이벤트 추적 및 시각화 시스템 | |
자가 최적화 브로커 | AI 기반 워크로드 분석 및 설정 자동화 기능 | |
신뢰성 / 확장성 | Partition / Sharding | 메시지 병렬 처리 및 확장을 위한 파티셔닝 기술 |
Replication | 장애/데이터 유실 방지를 위한 다중 복제 | |
DLQ (Dead Letter Queue) | 실패 메시지 별도 저장 후 재처리 가능하게 하는 큐 | |
ISR (In-Sync Replica) | 리더와 동기화된 복제본 집합 | |
실시간 처리 | Stream Processing | 이벤트를 실시간 분석, 알림, 변환 처리하는 기능 |
Flink, Storm, Spark Streaming | 주요 실시간 스트림 처리 엔진들 | |
표준 및 생태계 | AsyncAPI | 비동기 메시징용 API 명세 포맷 |
CloudEvents | 클라우드 간 이벤트 표준 메타데이터 포맷 | |
Avro / Protobuf / JSON Schema | 이벤트 메시지 포맷 및 스키마 정의 방식 | |
Apache Kafka / Pulsar / NATS | 대표적인 오픈소스 Event Broker 솔루션 | |
EventBridge / Event Hubs | AWS, Azure 등 관리형 이벤트 서비스 | |
기술 트렌드 | eBPF 기반 브로커 최적화 | 커널 레벨 필터링 및 라우팅 최적화를 위한 고급 기술 |
영속성과 지연 시간 균형 | NVRAM, SSD 등을 통한 저지연 고내구성 설계 | |
양자 내성 암호화 | 향후 양자 컴퓨팅 위협 대비 보안 기법 적용 연구 중 | |
탄소 발자국 최적화 | 에너지 효율성 향상 및 지속가능한 메시징 시스템 설계 | |
도메인 특화 솔루션 | IoT 특화 브로커 | 리소스 제약, 엣지 환경 대응용 경량 메시징 솔루션 (예: MQTT 기반) |
금융 특화 고성능 브로커 | 초저지연/고신뢰/규제 준수 메시지 처리 요구 대응 | |
AI/ML 파이프라인 통합 | 모델 학습/추론 워크플로우와 이벤트 시스템 통합 설계 |
반드시 학습해야 할 내용
🚀 카테고리 | 주제 | 핵심 항목 | 설명 |
---|---|---|---|
Messaging Theory | 전송 보장 | At-least-once / Exactly-once | 메시지 중복·손실 방지를 위한 전달 보장 수준 이해 |
Pub/Sub | 발행/구독/이벤트 분배 | 퍼블리셔와 구독자 간의 메시지 배포 구조 | |
Ack / Idempotency | ack(확인 응답) / 중복 처리 방지 | 메시지 처리 상태 확인 및 중복 트랜잭션 방지 | |
Streaming Platform | Apache Kafka 아키텍처 | 분산 로그 기반 구조 및 설정 | Kafka 내부 구조, 파티션, 브로커 구성 등 |
Partitioning | 파티션, 샤딩, 토픽 분할 | 스케일아웃 및 병목 해소 설계 기법 | |
Integration Design | Event Storming | 도메인 이벤트 중심 설계 기법 | 비즈니스 흐름을 중심으로 이벤트 모델링 |
Schema Registry | 스키마 등록소 및 버전 관리 | Avro/Protobuf 기반 메시지 구조 통제 | |
Observability | 모니터링 및 트레이싱 | 흐름 추적, 장애 탐지 | OpenTelemetry 등으로 이벤트 흐름 실시간 모니터링 |
Format & Schema | Avro / Protobuf 포맷 | 메시지 직렬화와 스키마 관리 | 효율적 포맷과 상호 운용성 유지 |
운영/관제 | 장애 복구 패턴 | DLQ, Replication | 실패 시 재처리와 데이터 복제 전략 |
보안 | 메시지 암호화/인증/인가 | TLS, OAuth, 인증/인가 정책 | 메시지 무결성과 접근 제어 보장 |
용어 정리
카테고리 | 용어 (영문) | 설명 |
---|---|---|
구조/역할 | Broker | 메시지/이벤트를 발행자와 구독자 간에 중계하는 중심 시스템 |
Producer (생산자) | 메시지를 생성하여 브로커에 발행하는 컴포넌트 | |
Consumer (소비자) | 브로커로부터 메시지를 수신하고 처리하는 컴포넌트 | |
Consumer Group (컨슈머 그룹) | 동일 토픽을 병렬 처리하는 소비자들의 논리적 그룹 | |
Exchange (교환소) | 메시지를 라우팅 규칙에 따라 큐에 분배하는 브로커 컴포넌트 | |
메시지 채널 | Topic (토픽) | 이벤트를 분류하고 구독할 수 있는 논리적 메시지 채널 |
Queue (큐) | 메시지를 순서대로 저장하고 처리 대기하는 구조 | |
Partition (파티션) | 병렬 처리와 확장을 위해 토픽을 나눈 단위 | |
Offset (오프셋) | 컨슈머가 토픽 내 메시지를 어디까지 처리했는지 나타내는 지표 | |
Segment (세그먼트) | 파티션의 물리적 파일 단위 | |
패턴/모델 | Pub/Sub (발행 - 구독) | 발행자가 메시지를 보내고, 구독자가 이를 수신하는 비동기 메시징 모델 |
Event Sourcing | 시스템 상태 변경을 이벤트로 저장하고, 재생하여 상태를 복원하는 방식 | |
CQRS (Command Query Responsibility Segregation) | 명령과 조회의 책임을 분리하여 성능과 확장성 확보 | |
Saga Pattern (사가 패턴) | 분산 트랜잭션 처리를 위한 이벤트 기반 보상 트랜잭션 패턴 | |
Event Mesh | 여러 브로커를 연결하여 메시지 전송을 통합한 글로벌 이벤트 라우팅 구조 | |
신뢰성/보장 | DLQ (Dead Letter Queue) | 처리 실패 메시지를 임시 저장해 재처리 또는 분석 가능하게 하는 큐 |
Replication (복제) | 장애 대비를 위해 메시지를 다수의 브로커에 복제 | |
ISR (In-Sync Replica) | 리더와 동기화된 복제본 세트 | |
QoS (Quality of Service) | 메시지 전달 보장 수준: At-most-once, At-least-once, Exactly-once | |
성능/운영 | Backpressure (백프레셔) | 소비 속도가 생산 속도를 따라가지 못할 때 처리량 제어 메커니즘 |
Rebalancing (리밸런싱) | 컨슈머 그룹 간 파티션 재할당 과정 | |
Watermark (워터마크) | 스트림 처리 시 시간 윈도우 계산 기준 | |
운영/도구 | Schema Registry (스키마 레지스트리) | 메시지 포맷 (Avro, JSON 등) 의 버전/유효성 관리 시스템 |
Tracing (트레이싱) | 이벤트 흐름 추적 및 분석 도구 (예: OpenTelemetry, Jaeger) | |
AsyncAPI | 메시지 기반 API 명세 정의 포맷 | |
오토스케일링 (Auto-scaling) | 시스템 부하에 따라 컴퓨팅 자원을 자동으로 조절하는 기능 | |
프로토콜 | AMQP | 고급 메시지 큐 프로토콜, 라우팅/보안 등 지원 |
MQTT | 경량 메시지 프로토콜, IoT 환경에 적합 | |
STOMP | 간단한 텍스트 기반 메시징 프로토콜 | |
이벤트 추출 | CDC (Change Data Capture) | DB 변경 이벤트를 실시간 메시지로 전환하는 기법 |
참고 및 출처
Message Broker & Event Broker
Message Broker Vs Event Broker 비교
- 메시지 브로커와 이벤트 브로커의 이해와 활용
- 메시지 브로커와 이벤트 브로커: 분산 시스템의 핵심 기술
- Message Broker vs Event Broker 비교 분석 - Riskified Tech
- 메시지 브로커 vs 이벤트 처리 도구 비교 - Upsolver
RabbitMQ Vs Kafka
Event-Driven Architecture & Event Mesh
- 이벤트 기반 아키텍처란? | Red Hat
- 이벤트 메쉬(Event Mesh)의 개념, 기능, 작동 방식, 사용 방법 | Red Hat
- Event-Driven Architecture 패턴 가이드 - Microsoft Azure
- 솔라스 Event Broker 아키텍처 예시
실무 적용 & 최적화 사례
플랫폼별 공식 문서
- Apache Kafka 공식 문서 (Event Broker 구조)
- AWS EventBridge 공식 페이지
- Azure Event Grid 개요
- Google Cloud Eventarc 소개
- AsyncAPI 공식 웹사이트