RabbitMQ 개념 정리

🔥Log·2024년 6월 7일
0

RabbitMQ

목록 보기
1/9

🐰 RabbitMQ


RabbitMQ는 AMQP 1.0를 만족하는 오픈소스 메세지 큐 서비스이다.

메세지 큐 또는 이벤트 큐 진영에서 가장 유명한 Kafka에 비해서 비교적 쉽고 간단한 구조를 갖고 있어서 라이트한 구조의 시스템에서는, RabbitMQ를 사용하는 것도 좋은 선택일 수 있다.

홈페이지 피셜로 RabbitMQ는 멱등성, 유연함, 메세지 전송의 신뢰를 보장하는 서비스라고 한다.



🧐 RabbitMQ 기본 구조


Event-Driven Architecture 대부분이 그렇겠지만 프로듀서, 컨슈머와 메세지 브로커로 전체적인 구조를 설명할 수 있다. 그 중에서 메세지 브로커의 역할을 RabbitMQ가 수행하게 된다.

RabbitMQ는 N개의 Exchange를 갖고, 하나의 Exchange는 여러 개의 Queue를 가질 수 있다.
하나의 Exchange와 하나의 Queue의 연결을 "바인딩"이라고 부른다.

클라이언트(프로듀서, 컨슈머)의 입장에서는 Exchange와 Connection을 맺어서 특정 Channel(Queue)에 데이터를 보내거나 구독하게 된다.



💻 Exchange


🔗 공식문서 - Exchange

Exchange는 프로듀서로부터 메세지를 받아서, Queue에 저장하는 역할을 한다.
Exchange는 Queue로 메세지를 라우팅하는 방식에 따라서 4개의 유형이 존재하는데, 하나 하나 알아보자.

1) Direct exchange

Direct exchange는 Routing key 값과 Routing key를 갖고 있는 Binding을 찾고 해당 바인딩이 가리키는 Queue에 데이터를 할당한다. 이런 특징으로 인해서 간단한 기능에 적합한 옵션이다.

2) Fanout exchange

fanout옵션은 Routing key 값과 무관하게, Exchange에 바인딩되어 있는 모든 Queue에 데이터를 전달하는 옵션이다.

3) Topic exchange

Routing key값의 패턴에 일치하는 이름을 갖고 있는 Queue에 데이터를 라우팅하는 옵션이다.

예를 들어서, animal.tiger, animal.lion이라는 Queue와 바인딩되어 있는 Topic exchange가 있다고 가정해보자.

이 때, Routing key 값을 animal.tiger라고 메세지를 보내면 animal.tiger 큐에만 데이터가 전해지고, animal.*라는 Routing key 값으로 메세지를 보내면, animal.이라는 문자열로 시작하는 모든 큐에 데이터가 전달되는 것이다.

4) Headers exchange

메세지의 Routing key 값은 무시되고, Headers에 정의된 Key:Value 값을 통해서 메세지가 라우팅된다.

Queue의 Arguments에 동일한 Key:Value가 존재하는 경우에만 라우팅한다.

✍️ x-match

Exchange와 Queue의 연결을 "바인딩"이라고 부른다고 위에서 이야기했는데, 이 바인딩에도 여러 설정을 추가할 수 있다.

그 중에 하나가 x-match라는 값이다. 바인딩의 Arguments에 x-match라는 키 값으로 all 또는 any라는 값을 지정할 수 있다.

  • all: 메세지 헤더의 모든 Key:Value와 바인딩 Arguments의 모든 Key:Value가 일치해야 메세지를 라우팅하는 옵션
  • any: 메세지 헤더 중 하나의 Key:Value와 바인딩 Arguments의 하나의 Key:Value만 일치해도 메세지를 라우팅하는 옵션

5) 추가 옵션

Exchange에는 Type 말고도 몇가지 옵션이 더 존재한다. 하나 하나 살펴보자.

  1. Durability: 브로커가 재시작할 때 Exchange가 어떻게 동작할지에 대한 옵션이다. Durable, Transient라는 값이 존재하고, Durable은 재시작해도 Exchange가 없어지지 않고, Transient는 브로커가 재시작하면 Exchange가 삭제되는 옵션이다.
  2. Auto delete: 이 옵션을 yes로 하면, 바인딩되어 있던 큐들이 모두 언바인딩되면, Exchange가 삭제된다.
  3. Internal: 이 옵션을 yes로 하면, 클라이언트가 직접 Exchange에 연결할 순 없게 된다.
  4. Arguments: 다양한 매개변수를 넘길 수 있다.


📥 Queue


🔗 공식문서 - Queues

큐는 다른 메세지 브로커 서비스들의 큐와 마찬가지로 FIFO구조를 갖고 있다. 데이터 또는 메세지를 쌓는 역할을 한다.

RabbitMQ는 Erlang으로 만들어져있는데, 하나의 큐는 하나의 Erlang 프로세스라고 생각하면 된다.

몇가지 옵션을 통해서 큐를 제어할 수 있는데, 이 옵션들을 알아보자.

1) Type

Queue는 4개의 유형으로 생성할 수 있다. 하나 하나 알아보자.

  1. Default for virtual host: 현재 vhost에 기본 값으로 설정된 큐 유형이 선택된다.
  2. Classic: RabbitMQ의 오리지널(?) 큐 유형이다. 데이터 복제를 하지 않으므로, 데이터의 안정성은 비교적 떨어지지만, 빠른 데이터 처리 성능을 갖게 된다.
  3. Quorum: 비교적 최근에 나온 큐이다. 데이터의 안정성을 가장 큰 우선순위로 두고 있는 큐이고, 큐의 복제를 통해서 이러한 기능을 수행한다.
  4. Stream: 다른 큐들과 달리 메세지를 삭제하지 않는 'Append-only' 모델이다. 데이터가 유지되면서도 복제도 되어서, 데이터의 안정성도 높다. 이 이외에도 매우 다양한 강점들을 갖고 있다.

2) Name

말 그래도 큐의 이름인데, 이름 이상의 역할을 하므로 잘 지어야한다. xxx.yyy.zzz와 같은 형태로 이름을 짓는 것이 권장된다.

amq.로 시작하는 큐들은 RabbitMQ가 내부적으로 사용하는 큐이다.

3) Durability

Exchange와 마찬가지로, 브로커가 재시작할 때 해당 큐를 생존시킬지를 결정하는 옵션이다.



⌛ Consuming messages


하나의 Queue는 여러 개의 컨슈머에 의해서 소비될 수 있는데, 이렇게 메세지를 소비하는 것에도 중요한 개념들이 있다. 한번 알아보자!

1) Ack Mode

Ack 모드는 컨슈머가 메세지를 소비하면서 해당 메세지를 어떤 상태로 만들 것인지에 대한 옵션이다.

이 옵션으로 큐에 Ack 또는 Negative Ack를 보낼지를 결정하고, 소비한 메세지를 큐에 다시 추가(Requeue)할 것인지를 결정할 수 있다.

Ack mode는 4가지 종류가 있다.

  1. Nack message requeue true: 수신한 메세지들을 큐에 다시 추가.
  2. Automatic ack: 메세지 소비 후, 큐에서 메세지를 제거한다.
  3. Reject requeue true: 수신한 메세지를 큐에 다시 추가.
  4. Reject requeue false: 수신한 메세지를 큐에 다시 추가하지 않음.

위 설명만으로는 어떤 경우에 각 Mode를 사용하는 것인지 알기 어려우니, 실제적인 에시로 이야기해보겠다.

먼저, Ack는 메세지 처리가 잘 이루어졌을 때 사용하면 되고, NackReject는 메세지 처리 중, 뭔가 에러가 발생한 경우에 사용하면 된다. Nack은 복수의 메세지를 한번에 처리할 수 있지만, Reject는 단 건의 메세지만 처리할 수 있다.

Automatic ackReject requeue false 모두 큐에서 제거하는 건데 뭐가 다르냐고 생각될 수 있는데, Reject requeue false는 메세지 자체에 이슈가 있어서, 다른 컨슈머가 처리하지 못하도록 큐에서 아예 제거하는 의미를 갖고 있다.

2) Messages

한번에 몇 개의 메세지를 읽어들일 것인지를 결정하는 옵션이다.



☕ 마무리


이번 글에서는 RabbitMQ의 주요 개념들에 대해서 알아보았다. 블로그에서 언급한 것의 몇 배는 더 많은 내용들이 있지만, 그 중에서도 기본적이고 핵심적인 것만 언급했다는 것을 참고해주면 좋을 것 같다.

다음 글에서는 RabbitMQ를 구동해보고 다양한 기능들을 사용해보도록 하겠다. 👍



🙏 참고


0개의 댓글

관련 채용 정보