업무중 rabbitmq 를 사용할 상황이 생겼다. 이전에도 메시지 브로커를 사용해본적이 있지만 rabbitmq 는 사용해본적이 없다. 그래서 이번 기회에 rabbitmq 의 개념과 구조에 대해서 정리해보려 한다.
1. 메시지 브로커
RabbitMQ 는 메시지 지향 미들웨어를 위한 프로토콜인 AMQP 를 Erlang 으로 구현한 시스템으로 producer 와 consumer 사이에서 메시지를 중계해주는 메시지 브로커이다. RabbitMQ 를 사용하면 프로그램 간에 비동기적인 메시지 송수신이 가능하다.
※ AMQP (Advanced Message Queuing Protocol)
메시지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜이다. 메시지 지향, 큐잉, 라우팅 (p2p, pub-sub), 신뢰성, 보안 등에 대해 정의하고 있다.
RabbitMQ 와 같은 메시지 브로커를 사용하면 다음과 같은 장점이 있다.
1. 비동기 (Asynchronous): 메시지의 전송과 관련된 작업들을 동기화 처리하지 않고 메시지 브로커를 통해 전송하여 처리하기 때문에 기존 동기화 방식에서 발생할 수 있는 병목현상을 방지할 수 있다.
2. 낮은 결합도 (Decoupling): 메시지를 생산하고 발송하는 서비스와 수신하여 처리하는 서비스를 별개의 서비스로 분리하여 독립적으로 동작하여 서비스간의 결합도가 낮아지게 된다.
3. 확장성 (Scalable): 다수의 프로세스들이 메시지 브로커를 통해 메시지를 송수신 할 수 있기 때문에 확장성과 분산 처리에 이점이 있다.
4. 탄력성 (Resilience): 메시지를 처리하는 서비스에 문제가 있어 종료되더라도 메시지 큐에 메시지가 남아있어서 서비스 재시작시에 메시지를 다시 수신하여 처리할 수 있다.
5. 보장성 (Guarantee): 메시지 큐에 보관되는 메시지는 모두 수신 서비스에 전달된다는 일반적인 보장을 제공한다.
메시지 브로커로 어떤 솔루션과 기능을 사용하느냐에 따라 메시지의 저장 기능, 전송 보장 등의 차이가 있지만 기본적으로 위와 같은 장점들을 제공해준다.
2. RabbitMQ 구조 및 개념
Producer ---> | Exchange --- (binding) ---> Queue | ---> Consumer
RabbitMQ 의 시스템은 크게 Producer, Broker, Consumer 로 구분되며 Broker 내부에는 Exchange, Binding, Queue 순으로 동작이 실행된다.
- Producer
Producer 는 메시지를 생성하고 발송하는 서비스이다. Publisher 라고도 불리며 Broker 로 메시지를 보내어 Consumer 가 이를 수신하여 처리하도록 한다.
RabbitMQ 의 Producer 가 메시지를 발송할 때는 Broker 의 Queue 로 직접 전송하는 것이 아니라 Broker 의 Exchange 로 전송한다.
- Consumer
Broker 에 전송된 메시지를 수신하여 이를 처리하는 서비스이다. Broker 에 저장된 Queue 로부터 메시지를 읽어온다.
- Exchange
Exchange 는 Broker 내부에 위치하여 Producer 로부터 전달받은 메시지를 Queue 로 전달하는 객체이다. Direct, Topic, Headers, Fanout 등 4가지 타입이 있으며, 입력된 메시지를 Queue 로 전달할 때에는 타입에 따라 Binding 설정을 참고하여 적절한 Queue 로 전달한다.
- Binding
Binding 은 Exchange 와 Queue 를 연결하는 관계, 설정이다. 초기의 Exchange 는 아무 Queue 와도 연결되어 있지 않다. Application 은 Exchange 에 Queue 를 binding 해주어 둘을 연결할 수 있는데, 이때 routing key 와 같은 값들을 설정하여 Exchange 타입에 따른 메시지 전송시에 사용할 수 있다.
- Queue
Broker 내부에서 메시지를 임시적으로 저장하는 장소이다. Consumer 들은 지정된 Queue 에 저장되어 있는 메시지를 읽어온다.
Queue 는 RabbitMQ 서버가 설치되는 호스트의 디스크 용량 및 메모리에 한정된다.
3. Exchange
Exchange 는 입력된 메시지를 Exchange 타입과 Binding 설정에 따라 적절한 Queue 로 전달하는 객체이다. Exchange 는 다음과 같은 속성을 가진다.
Name: Exchange 이름.
Type: 메시지 전달 방식. [Direct, Topic, Headers, Fanout]
Durability: 브로커 재시작시 유지 여부.
- Durable: 브로커가 재시작 되어도 Exchange 는 디스크에 저장되어 유지된다.
- Transient: 브로커기 재시작 되면 삭제된다.
Auto-delete: Exchange 에 연결된 Queue 가 하나도 없으면 자동으로 삭제된다.
Exchange 가 메시지를 Queue 로 전달하는 방식에는 다음의 4가지 타입을 가지고 있다.
- Direct Exchange
메시지에 포함된 routing key 를 기반으로 Queue 에 메시지를 전달한다. 각 Queue 마다 여러개의 routing key 를 지정할 수 있는데, Direct Exchange 는 메시지의 routing key 와 동일한 키로 지정된 Queue 로 메시지를 전달한다.
RabbitMQ 의 Default Exchange 는 Direct Exchange 이며 RabbitMQ 에서 생성되는 Queue 가 자동으로 binding 되는데, 이때 각 Queue 의 이름이 routing key 로 지정된다.
- Topic Exchange
메시지에 포함된 routing key 를 기반으로 Queue 에 전달하는 방식으로, 키 전체가 일치하거나 패턴이 일치하는 모든 Queue 로 메시지가 전달된다.
여러 Consumer 에서 메시지 형태에 따라 선택적으로 수신해야 하는 경우와 같이 다양한 패턴 구현에 활용될 수 있다.
Topic Exchange 에서 binding key 는 점(.) 으로 구분되는 단어의 조합으로 정의된다. '*' 또는 '#' 을 사용할 수 있으며, '*' 는 정확히 하나의 단어를 대체하고, '#' 는 0개 혹은 여러개의 단어를 대체하는 용도로 사용된다. (Direct Exchange 에서는 특수기호를 이용한 와일드카드 기능을 지원하지 않는다.)
- Headers Exchange
메시지 라우팅에 요청의 header 를 사용하는 방식이다. binding key 만 사용하는 이전 방식들보다 더 다양한 속성을 사용할 수 있다.
Header 의 [key:value] 형식으로 이루어진 값들을 비교하여 일치하는 Queue 에게 메시지를 전송하는 방식이다. Header Exchange 를 사용하면 routing key 속성은 무시되고 headers 속성의 값만 비교한다.
Header Exchange 는 x-match 값에 따라 동작 방식에 차이가 있다.
- 'x-match = any': 헤더 테이블의 값 (key-value pair) 중 하나가 연결된 값 중 하나와 일치하면 메시지를 전달
- 'x-match = all': 헤더 테이블의 값 (key-value pair) 과 모든 값이 일치해야 메시지를 전달
- Fanout Exchange
Routing key 에 관계없이 Exchange 에 등록된 모든 Queue 에 메시지를 전달하는 broadcasting 방식으로 동작한다.
4. Queue
Queue 는 메시지가 임시로 저장되는 곳으로 다음과 같은 속성을 가진다.
Name: Queue 이름. 'amq.' 은 예약어이기 때문에 사용할 수 없다.
Durability: 브로커 재시작시 유지 여부.
- Durable: 브로커가 재시작 되어도 Queue 는 디스크에 저장되어 유지된다.
- Transient: 브로커기 재시작 되면 삭제된다.
Auto-delete: 마지막 Consumer 가 consume 을 끝낼 경우 자동으로 삭제된다.
Argument: 메시지 TTL, Max Length 같은 기능 설정을 위한 매개변수.
5. Dispatch 방식
하나의 Queue 에 여러 개의 Consumer 가 연결되어 있는 경우 RabbitMQ 는 Round-Robin 방식을 통해 Consumer 에게 메시지를 균등하게 분배한다.
하지만 Round-Robin 방식이 항상 효율적이지는 않다. 특정 작업의 시간이 오래 걸리는 경우 해당 작업을 수행하는 Consumer 에는 계속해서 작업이 쌓이는 반면 다른 Consumer 는 가벼운 작업들만 처리하여 비교적 여유로운 상태에 있게 된다.
이러한 상황을 예방하기 위해서 RabbitMQ 에서는 Prefetch 를 설정할 수 있다. Prefetch 는 Queue 의 메시지를 Consumer 의 메모리에 쌓아둘 수 있는 최대 메시지의 양이다. Prefetch Count 의 값을 1로 설정하면 하나의 메시지가 처리되기 전에는 새로운 메시지를 받지 않기 때문에 시간이 오래 걸리는 작업을 수행 중일때는 작업을 다른 Consumer 로 분산시킬 수 있다.
6. Channel
Consumer 에서 Broker 로 많은 연결을 맺어 사용하는 것은 리소스의 낭비가 될 수 있다. RabbitMQ 는 Channel 이라는 개념을 통해 하나의 TCP 연결을 맺고 이를 공유하여 Broker 와 Consumer 가 통신할 수 있도록 한다.
[Reference]
- https://wildeveloperetrain.tistory.com/317
RabbitMQ 개념과 구조 정리 (Exchange Type, Dispatch 등)
RabbitMQ 개념과 구조 정리 RabbitMQ란? 'RabbitMQ'는 AMQP를 구현하여 메시지 생성자와 소비자 사이에서 메시지를 중계해 주는 '메시지 브로커'입니다. * AMQP(Advenced Message Queuing Protocol) 메시지 지향 미들
wildeveloperetrain.tistory.com
- https://velog.io/@sdb016/RabbitMQ-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90
[RabbitMQ] 기초 개념
AMQP를 구현한 오픈소스 메세지 브로커이다.producers에서 consumers로 메세지(요청)를 전달할 때 중간에서 브로커 역할을 한다.사용하는 케이스는 다음과 같다.요청을 많은 사용자에게 전달할 때요청
velog.io
- https://jonnung.dev/rabbitmq/2019/02/06/about-amqp-implementtation-of-rabbitmq/#gsc.tab=0
RabbitMQ 동작 이해하기 | 조은우 기술 블로그
RabbitMQ 동작 이해하기 비동기 작업 큐(예: Celery)를 사용하려면 중간 단계에 Broker 라고 부르는 메시지 큐가 항상 등장한다. 메시지 큐에는 RabbitMQ, ActiveMQ, ZeroMQ, Kafaka 등이 대표적이다. 이 포스트는
jonnung.dev
'기타' 카테고리의 다른 글
[nginx] ssl 인증서 적용 (0) | 2025.04.24 |
---|---|
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 9. 웹 크롤러 설계 (0) | 2025.04.06 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 8. URL 단축기 설계 (0) | 2025.03.18 |
[PostgreSQL] DB 백업 - pg_dump (0) | 2025.03.17 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 7. 분산 시스템을 위한 유일 ID 생성기 설계 (0) | 2025.03.13 |