Direct vs. Topic vs. Fanout: 올바른 교환 유형 선택하기
정확한 라우팅, 와일드카드 라우팅 또는 브로드캐스트 전달에 따라 RabbitMQ direct, topic 또는 fanout 교환을 선택하세요.
Direct vs. Topic vs. Fanout: 올바른 교환 유형 선택하기
RabbitMQ 교환 유형은 생산자가 메시지를 게시한 후 메시지가 전달되는 위치를 제어합니다. 잘못된 교환을 선택하면 개인 작업이 브로드캐스트되거나, 일치하는 라우팅 키가 없는 메시지가 손실되거나, 나중에 관리가 어려운 하드코딩된 라우팅 규칙이 생길 수 있습니다.
실용적인 선택은 간단합니다: 정확한 라우팅에는 direct, 브로드캐스트에는 fanout, 명명 체계를 통한 와일드카드 라우팅에는 topic을 사용하세요.
RabbitMQ 라우팅 작동 방식
생산자는 큐가 아닌 교환에 직접 메시지를 게시합니다. 교환은 메시지 라우팅 키를 큐 바인딩과 비교한 후 교환 유형에 따라 메시지를 라우팅합니다.
세 가지 용어가 중요합니다:
- 교환(Exchange): 게시된 메시지를 수신합니다.
- 큐(Queue): 소비자가 메시지를 수신할 때까지 메시지를 저장합니다.
- 바인딩(Binding): 큐를 교환에 연결하며, 때로는 바인딩 키를 사용합니다.
일치하는 큐가 없고 메시지가 mandatory로 표시되지 않은 경우, RabbitMQ는 라우팅 불가능한 메시지를 삭제할 수 있습니다. 중요한 흐름의 경우 게시자 확인(publisher confirms)을 사용하고 반환된 메시지를 처리하세요.
Direct 교환
Direct 교환은 바인딩 키가 메시지 라우팅 키와 정확히 일치하는 큐로 메시지를 라우팅합니다.
라우팅 선택이 명확하고 정확할 때 사용하세요. 로그 심각도, 작업 유형 또는 정확한 이름으로 충분한 테넌트별 큐가 좋은 예입니다.
예를 들어, error_queue를 error로, info_queue를 info로 바인딩합니다. 라우팅 키 error로 게시된 메시지는 error_queue로 전달되고, info로 게시된 메시지는 info_queue로 전달됩니다. 두 큐가 error로 바인딩되면 두 큐 모두 메시지 사본을 받습니다. 동일한 큐의 소비자는 여전히 해당 큐의 메시지를 경쟁적으로 소비합니다.
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs_direct', exchange_type='direct')
channel.basic_publish(
exchange='logs_direct',
routing_key='error',
body=b'데이터베이스 연결 실패'
)
connection.close()
라우팅 키가 안정적이고 와일드카드 매칭이 필요하지 않을 때 direct를 선택하세요.
Fanout 교환
Fanout 교환은 교환에 바인딩된 모든 큐로 모든 메시지를 라우팅합니다. 라우팅 키는 무시됩니다.
모든 구독자가 동일한 메시지를 수신해야 하는 브로드캐스트 이벤트에 사용하세요. 일반적인 경우로는 캐시 무효화, 사용자 프로필 업데이트 이벤트, 배포 알림 또는 실시간 상태 업데이트가 있습니다.
예를 들어, user_updates fanout 교환은 email_queue, search_index_queue, analytics_queue 세 개의 큐에 공급할 수 있습니다. 하나의 게시된 프로필 업데이트가 세 서비스 모두에 도달합니다.
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='user_updates', exchange_type='fanout')
channel.basic_publish(
exchange='user_updates',
routing_key='',
body=b'사용자 123이 표시 이름을 변경했습니다'
)
connection.close()
라우팅 로직이 중요하지 않고 바인딩된 모든 큐가 사본을 받아야 할 때 fanout을 선택하세요.
Topic 교환
Topic 교환은 점으로 구분된 라우팅 키를 와일드카드 바인딩 키와 일치시켜 라우팅합니다. 이벤트 유형마다 다른 교환을 만들지 않고도 유연한 라우팅을 제공합니다.
Topic 바인딩은 두 가지 와일드카드를 사용합니다:
*는 정확히 한 단어와 일치합니다.#는 0개 이상의 단어와 일치합니다.
예를 들어, order.created.us 및 order.cancelled.eu와 같은 라우팅 키의 경우:
order.*.us는 미국 주문에 대한 하나의 작업과 일치합니다.order.created.#는 모든 지역 및 선택적 추가 단어에 걸쳐 생성된 주문과 일치합니다.#.eu는eu로 끝나는 이벤트와 일치합니다.
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='events_topic', exchange_type='topic')
channel.basic_publish(
exchange='events_topic',
routing_key='order.created.us',
body=b'주문 9001 생성됨'
)
connection.close()
소비자가 더 큰 이벤트 스트림의 필터링된 하위 집합(예: service.environment.severity, entity.action.region, tenant.event.priority)이 필요할 때 topic을 선택하세요.
빠른 선택 가이드
| 필요 | 교환 유형 | 예시 |
|---|---|---|
| 정확한 일치 라우팅 | Direct | error, invoice.created |
| 모든 구독자에게 브로드캐스트 | Fanout | 캐시 제거 이벤트 |
| 와일드카드 라우팅 | Topic | orders.*.us, logs.# |
일관성 없는 라우팅 키를 위한 덤핑 그라운드로 topic 교환을 사용하지 마세요. 초기에 명명 규칙을 정하고 문서화하며, 소비자가 필터링하는 방식에 따라 단어를 광범위에서 구체적으로 또는 엔터티에서 작업 순서로 정렬하세요.
핵심 요약
정확한 대상에는 direct 교환, 브로드캐스트에는 fanout 교환, 소비자가 와일드카드 필터가 필요할 때는 topic 교환을 사용하세요. 경로를 하나의 정확한 레이블로 설명할 수 있다면 direct를 사용하세요. 모든 사람이 메시지를 필요로 한다면 fanout을 사용하세요. 구독자가 패턴을 필요로 한다면 topic을 사용하세요.