RabbitMQ 에 대해서 AI의 도움을 받아 정리 해봅니다.
- RabbitMQ는 AMQP(Advanced Message Queuing Protocol)를 따르는 오픈소스 메시지 브로커 제품 중 하나입니다.
- 다수의 작업을 처리할 때 웹 애플리케이션 서버에서 모든 요청을 처리하지 않고, 메시지 브로커를 통해 처리자에게 작업을 위임하는 방식을 지원합니다.
0. 구조
1) Message: 처리해야 할 내용이 담긴 데이터입니다.2) Producer: Message를 생성하고, Exchange에 Message를 전달합니다.3) Exchange: Producer로부터 받은 Message를 Queue에 전달해주는 역할을 합니다.4) Queue: Message를 저장하고, Consumer들에게 Message를 전달합니다.5) Consumer: Queue로부터 Message를 받아 처리합니다.
1. Message Broker:
- Message Broker는 송신자(Producer)와 수신자(Consumer) 간의 효율적인 메시지 전달을 중재하는 중요한 역할을 합니다.
- RabbitMQ는 메시지 브로커로서 Message를 받아 Exchange로 전달하고, Exchange에서 Queue로 라우팅하여 Consumer에게 전달합니다.
2. Exchange:
- Exchange는 Producer로부터 받은 Message를 적절한 Queue에 전달해주는 역할을 합니다.
- Exchange에는 다양한 타입이 있으며, Fanout, Direct, Topic, Headers 등이 있습니다.
- Exchange는 라우팅 규칙을 정의하고, Binding을 통해 Queue와 연결됩니다.
3. Queue:
- Queue는 메시지를 저장하는 공간으로, Consumer가 Message를 처리하기 위해 대기하는 곳입니다.
- Exchange로부터 라우팅된 Message가 Queue에 저장되고, Consumer가 이를 가져와 처리합니다.
4. Producer:
- Producer는 Message를 생성하여 RabbitMQ에 보냅니다.
- Exchange에게 Message를 보내며, Exchange는 이를 적절한 Queue에 전달합니다.
5. Consumer:
- Consumer는 Queue로부터 Message를 가져와 실제 작업을 처리합니다.
- 여러 Consumer가 하나의 Queue를 공유할 수 있으며, Round-Robin 방식으로 Message가 분배됩니다.
6. Binding:
- Exchange와 Queue 사이의 연결을 의미합니다.
- Binding은 Exchange의 라우팅 규칙과 Queue를 연결하여 Message 전달을 가능하게 합니다.
Exchange 타입
1. Fanout:
- 모든 Queue에 동일한 Message를 브로드캐스트합니다.
- 하나의 Message를 여러 Consumer에게 전달할 때 유용합니다.
2. Direct:
- Message를 특정 Queue로 라우팅하기 위해 Routing Key를 사용합니다.
- Routing Key와 Queue 이름이 정확히 일치하는 Queue로 Message가 전달됩니다.
3. Topic:
- Topic Exchange는 패턴을 사용하여 Message를 여러 Queue에 전달합니다.
- *(star)*와 #(hash)를 사용하여 유연한 패턴을 생성할 수 있습니다.
4. Headers:
- Header의 key-value 쌍과 Binding 시 설정한 argument의 key-value 쌍이 일치하면 Message를 전달합니다.
- 복잡한 라우팅 규칙을 지정할 때 사용됩니다.
Routing Key와 Binding
- Routing Key: Message를 특정 Exchange에서 특정 Queue로 라우팅하는 데 사용되는 키입니다. Direct와 Topic Exchange에서 주로 사용됩니다.
- Binding: Exchange와 Queue 사이의 연결을 말합니다. Producer는 Exchange에 Message를 보내고, Consumer는 Exchange와 Queue를 Binding하여 Message를 받습니다.
RabbitMQ 활용 시나리오
- 주문 처리 시스템: 주문 요청이 들어오면 RabbitMQ를 통해 주문 처리 작업을 다양한 Consumer에게 분산하여 처리할 수 있습니다.
- 로그 처리 시스템: 로그 메시지를 RabbitMQ를 통해 Queue에 저장하고, 여러 로그 분석 서비스가 이를 읽어와 분석할 수 있습니다.
RabbitMQ는 다양한 시나리오에서 비동기 메시징을 구현하고, 시스템 간의 커뮤니케이션을 효율적으로 처리하는 데 사용됩니다.
위에서 설명한 개념과 용어들은 RabbitMQ를 이해하고 활용하는 데 필수적인 내용입니다.
회사에서 Kafka를 쓰지 않고, Rabbit MQ를 쓴 이유는 RabbitMQ와 Apache Kafka는 모두 메시지 브로커로서 사용되지만, 각각의 기능과 특성이 다르기 때문이라고 합니다.
RabbitMQ의 장점:
1. 유연한 라우팅: RabbitMQ는 다양한 Exchange 타입을 제공하여 유연하고 복잡한 라우팅 규칙을 설정할 수 있습니다. Fanout, Direct, Topic, Headers 등 다양한 라우팅 패턴을 지원하므로 메시지의 흐름을 더 세밀하게 제어할 수 있습니다.
2. 풍부한 클라이언트 라이브러리: RabbitMQ는 다양한 언어와 프레임워크를 지원하는 클라이언트 라이브러리를 제공합니다. 따라서 여러 플랫폼에서 RabbitMQ를 쉽게 통합할 수 있습니다.
3. 다양한 프로토콜 지원: RabbitMQ는 AMQP 외에도 STOMP, MQTT 등 다양한 프로토콜을 지원합니다. 이는 다양한 클라이언트와 시스템과의 통합을 용이하게 합니다.
4. 유연한 메시지 패턴: Exchange와 Queue의 다양한 조합을 통해 유연하고 복잡한 메시지 패턴을 구현할 수 있습니다. 이는 메시지 라우팅과 처리를 효과적으로 제어할 수 있음을 의미합니다.
5. 높은 신뢰성: RabbitMQ는 메시지 지속성을 보장하며, 메시지가 안전하게 전달되고 손실되지 않음을 보장합니다.
6. 관리 도구: RabbitMQ는 관리 및 모니터링 도구를 제공하여 큐 및 메시지의 상태를 쉽게 모니터링하고 관리할 수 있습니다.
Kafka와의 비교에서 RabbitMQ의 장점:
- RabbitMQ는 다양한 메시지 라우팅 패턴과 유연한 메시지 패턴을 지원하며, 높은 신뢰성을 제공합니다. 이는 다양한 메시징 요구사항을 충족시킬 수 있음을 의미합니다.
- RabbitMQ는 AMQP 및 다른 프로토콜을 지원하여 다양한 플랫폼과 통합이 쉬우며, 관리 도구를 통한 모니터링 및 관리 기능도 강화됩니다.
- RabbitMQ는 많은 클라이언트 라이브러리와 문서화된 자원을 제공하여 팀이나 개발자들이 RabbitMQ를 효과적으로 사용할 수 있도록 돕습니다.
물론 상황에 따라 Kafka가 더 적합한 경우도 있을 수 있습니다.
예를 들어, 대량의 데이터 스트림을 실시간으로 처리해야 하는 경우나 로그 분석, 이벤트 소싱 등의 사용 사례에서 Kafka가 더 적합할 수 있습니다. 선택은 프로젝트의 요구사항과 아키텍처에 따라 달라질 것입니다.
위에 ChatGpt가 입력해 준 자료를 정리해 보면 대량의 데이터를 주고 받는 경우가 많으므로 Kafka가 적합한 것 같으나... 일단 설계시에 Rabbit MQ를 사용했기 때문인 것으로 보이기는 합니다.
일단 개념적인 부분을 인지하고, 사용 예제를 만들어 보면 아래와 같습니다.
이 예제에서는 RabbitMQ의 기본 개념을 사용하여 간단한 메시지를 Producer에서 전송하고, Consumer에서 받는 방법을 보여줄 것입니다.
전제 조건:
1. RabbitMQ 서버가 설치되어 있어야 합니다.
2. Java 개발 환경이 설정되어 있어야 합니다.
의존성 추가:
Gradle을 사용하는 경우 `build.gradle` 파일에 다음 의존성을 추가합니다:
dependencies {implementation 'com.rabbitmq:amqp-client:5.14.0'}
Maven을 사용하는 경우 `pom.xml` 파일에 다음 의존성을 추가합니다:
<dependencies><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.14.0</version></dependency></dependencies>
Producer 예제:
import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Channel;public class Producer {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost"); // RabbitMQ 서버 호스트 주소 설정try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {channel.queueDeclare(QUEUE_NAME, false, false, false, null);String message = "Hello, RabbitMQ!";channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println(" [x] Sent '" + message + "'");}}}
Consumer 예제:
import com.rabbitmq.client.*;public class Consumer {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {channel.queueDeclare(QUEUE_NAME, false, false, false, null);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}}}
위의 예제는 RabbitMQ 서버가 로컬 호스트(localhost)에서 실행 중인 경우에 작동합니다.
만약 다른 호스트에서 실행 중인 RabbitMQ 서버를 사용한다면, `setHost` 메서드의 호스트 주소를 해당 서버의 주소로 변경해야 합니다.
이 예제는 간단한 메시지를 보내고 받는 방식을 보여줍니다. RabbitMQ의 더 다양한 기능을 활용하려면 더 복잡한 구성과 설정이 필요할 수 있습니다.
추신.
Kafka는 대용량의 분산 로그 트래픽을 처리한다는 점에서 유리하다면,
RabbitMQ는 높은 처리량보다는 지정된 수신인에게 원하는 방식으로 메시징을 신뢰성 있게 전달하는데 초점이 맞춰져 있습니다.
그래서 RabbitMQ 경우에는 대용량 트래픽에는 조금 불리한 점이 있는 대신 익스체인지 타입이나 라우팅 정책에 따라서 동작 방식을 선택할 수가 있는 장점이 있습니다.
라고 명확하게 차이를 기재해 주어 이해에 도움이 되었습니다.
댓글
댓글 쓰기