메시지 브로커 패턴은 발신자와 수신자를 분리해 비동기 메시지 기반 통신을 가능하게 하는 아키텍처 패턴이다. RabbitMQ, Apache Kafka, Redis Pub/Sub, AWS SQS/SNS가 대표적 구현체다.
주요 메시지 브로커 패턴
| 패턴 | 설명 | 구현체 |
|---|
| 메시지 큐 (Queue) | 1:1 비동기 작업 | RabbitMQ, SQS |
| Pub/Sub | 1:N 이벤트 브로드캐스트 | Kafka, Redis, SNS |
| 요청/응답 | 비동기 RPC | RabbitMQ RPC |
| 팬아웃 | 여러 큐로 복사 | SNS → SQS |
RabbitMQ 기본 패턴
python
# 발신자 (Publisher)
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# 직접 큐
channel.queue_declare(queue='task_queue', durable=True)
channel.basic_publish(
exchange='',
routing_key='task_queue',
body='처리할 작업 데이터',
properties=pika.BasicProperties(
delivery_mode=pika.spec.PERSISTENT_DELIVERY_MODE, # 영구 보존
)
)
# 수신자 (Consumer)
def callback(ch, method, properties, body):
print(f"수신: {body.decode()}")
# 처리 완료 확인 (ACK)
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1) # 한 번에 1개씩
channel.basic_consume(queue='task_queue', on_message_callback=callback)
channel.start_consuming()
Kafka Pub/Sub 패턴
python
from kafka import KafkaProducer, KafkaConsumer
import json
# 프로듀서
producer = KafkaProducer(
bootstrap_servers=['localhost:9092'],
value_serializer=lambda v: json.dumps(v).encode()
)
producer.send('user-events', {
'event': 'user_registered',
'user_id': 12345,
'timestamp': '2025-01-01T00:00:00Z'
})
# 컨슈머 그룹
consumer = KafkaConsumer(
'user-events',
bootstrap_servers=['localhost:9092'],
group_id='notification-service', # 컨슈머 그룹 (부하 분산)
value_deserializer=lambda m: json.loads(m.decode())
)
for message in consumer:
print(f"오프셋 {message.offset}: {message.value}")
배달 보장 수준
| 수준 | 설명 | 사용 시나리오 |
|---|
| At-most-once | 최대 1번 (유실 가능) | 로그, 메트릭 |
| At-least-once | 최소 1번 (중복 가능) | 이메일, 알림 |
| Exactly-once | 정확히 1번 | 결제, 재고 |
관련 개념