RabbiMQ - 2 Hello World

강민욱·2024년 4월 20일

rabbitMQ

목록 보기
2/2

1. 개요

소프트웨어 구성요소(서비스)간의 디커플링은 소프트웨어 설계의 가장 중요한 부분중 하나이다. 그 방법중 하나는 구성요소(서비스)간 비동기식 통신을 제공하는 메시징 시스템을 사용하는 것이다.

RabbitMQ가 그중 하나란 얘기다.

2. 메시징 모델

먼저 메시징이 어떻게 동작하는 살펴보자
메시징 시스템과 상호작용하는 어플리케이션에는 producers, consumers 두가지가 있다. producers는 broker에게 메시지를 발송하고 consumers는 broker로부터 메시지를 받는다. 보통 program(구성요소)은 다른 머신(서버라 생각하는게 더 쉬울거 같다)에서 동작하고 RabbitMQ는 그들 사이에서 통신 미들웨어 역할을 한다.

3. 용어설명

  • Producing : 메시지를 보내는것, 메시지를 보내는 프로그램이 Producer
  • Queue : RabbitMQ에서 우편함 역할, 메시지는 RabbitMQ, 우리의 어플리케이션을 통해 전달되지만 저장은 Queue만 저장될 수 있다. Queue는 메모리, 디스크용량에 의해 제한을 받으며, 본질적으로 큰 메시지 버퍼이다. 하나의 Queue에 여러 Producer 메시지를 보내고, 여러 Consumer가 메시지를 받는다.
    producer, consumer, broker가 모두 같은 host에 존재할 필요는 없다. 실제로 그러진 않지만 하나의 어플리케이션이 producer, consumer 두 역할을 같이 할 수도 있다.
  • Consumer : Producer와 반대의 개념, 메시지를 받는쪽이다.

4. Hello world

RabbitMQ는 여러 프로토콜을 지원하는데 이 튜토리얼에서는 메시징을 위한 개방형 프로토콜인 AMQP 0-9-1과 java로 된 RabbitMQ 클라이언트를 사용한다.
튜토리얼에서는 slf4j라이브러리를 사용하는데 maven, gradle을 사용하는 경우에는 amqp-client를 사용해도 된다.

4.1 RabbiMQSend

용어에서 보자면 Producer역할이다.
https://www.rabbitmq.com/tutorials/tutorial-one-java 튜토리얼에 있는 소스이다.

package my.study.rabbitmqstudy.rabbitmp;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class RabbiMQSend {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) {
        ConnectionFactory factory = new ConnectionFactory();

        Connection connection = null;
        Channel channel = null;
        try{
            factory.setHost("localhost");
            connection = factory.newConnection();
            channel = connection.createChannel();

            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            String message = "이 편지는 영국에서 시작되어2";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TimeoutException e) {
            throw new RuntimeException(e);
        }
    }
}

QUEUE_NAME으로 queueDeclare메소드를 이용하여 queue를 선언하고 basicPublish로 원하는 큐를 지정하여 메시지를 보낸다.

4.2 RabbitMQRecv

용어에서 보자면 Consumer역할이다.

package my.study.rabbitmpstudyrecv.rabbitmp;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.concurrent.TimeoutException;

public class RabbitMQRecv {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) {
        ConnectionFactory factory = new ConnectionFactory();

        Connection connection = null;
        Channel channel = null;
        try{
            factory.setHost("localhost");
            connection = factory.newConnection();
            channel = connection.createChannel();

            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
              String message = new String(delivery.getBody(), "UTF-8");
              System.out.println("Message recieve : "+message);
                System.out.println(" 받은시간 : " + LocalDateTime.now());
            };

            channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TimeoutException e) {
            throw new RuntimeException(e);
        }
    }
}

QUEUE_NAME으로 queueDeclare메소드를 이용하여 queue를 선언한다, producer쪽은 보내기위한 queue를 선택한 것이라면 consumer쪽은 받을 queue를 선택하는 것이다. basicConsume메소드를 통해서 대기를 시작하면 된다.

4.3 결과

RabbiMQSend쪽 콘솔이다.

RabbitMQRecv쪽 콘솔이다.

보낸시간과 받은시간을 비교하면 0.01초만에 consumer쪽에서 수신하였다.

5. 결론

이렇게 HTTP통신으로 데이터를 주고 받는게 아닌 message를 통해서 시스템간에 정보를 주고 받는것을 요즘 흔히 말하는 event기반 시스템이라 부르는 거 같다.

profile
백엔드 개발자

0개의 댓글