RabbitMQ 정리 및 설정

박우진·2024년 12월 18일

Network/Server

목록 보기
1/12

메시지 큐

  • 프로세스 혹은 프로그램 간에 데이터를 교환할 때 사용하는 통신 방법 중 하나
  • 메시지 지향 미들웨어(Message-Oriented middleware) 라고도 함
  • 큐이기 때문에 FIFO(First IN First Out) 방식으로 구현됨

메시지 큐의 장점

  • 비동기: 동기적으로 처리하지 않기 때문에 결합도를 낮춰줌
  • 탄력성: 일부 실패 하거나 장애가 발생하더라도 전체에 영향을 주지 않음
  • 재사용성: 실패 시 다시 사용 가능
  • 신뢰성: 과정을 확인 할 수 있음
  • 확장성: 큐에 메시지를 보낼 수 있음

AMQP 란?

  • Advanced Message Queue Protocol
  • 효율적으로 메시지를 교환하기 위해 탄생한 프로토콜
  • 결합도를 낮춰주기 때문에 장애가 발생하면 영향이 적다
  • 메시지 브로커이벤트 브로커로 나뉨

메시지 브로커

  • 메시지 큐를 저장하고 보내주는 기능을 한다
  • Consumer 데이터는 짧은 시간이 지나면 자동으로 삭제가 된다
  • ex) RabbitMQ

이벤트 브로커

  • 메시지 브로커의 기능에 Consumer 데이터가 재사용 가능하다
  • ex) Kafka

브로커

  • Producer: 요청을 보내는 주체
  • Exchange: Producer 로부터 메시지를 받아 Queue로 처리해주는 역할
  • Queue: Consumer에 보내기 전 Exchange에서 수신 받은 메시지를 저장하는 저장소
  • Consumer: 메시지를 소비하는 주체
  • Binding: Exchange와 Queue의 연결을 나타냄(라우팅을 결정하는 과정)

RabbitMQ 란?

AMQP로 구현된 오픈소스 메시지 브로커

RabbitMQ의 Exchange 타입

타입동작 방식Routing Key
Direct라우팅 키가 정확하게 일치하는 큐에 메시지 전달 (1:1)sample.routing.key
Fanout바인딩된 모든 큐에 동일한 메시지 전달 (1:N)사용하지 않음
Topic라우팅 키 패턴의 일치 여부에 따라 메시지 라우팅 (1:N)sample.routing.# (*도 가능)
Headers메시지 헤더의 Key-Value 쌍을 기반으로 메시지가 특정 큐로 전달사용하지 않음

RabbitMQ 설정

도커 설정

docker pull rabbitmq:management
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
따로 username과 password 설정 가능
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 --restart=unless-stopped -e RABBITMQ_DEFAULT_USER=username -e RABBITMQ_DEFAULT_PASS=password rabbitmq:management
로컬 환경 접속 링크

http://localhost:15672

Exchanges 기능
  • 하단에 내리면 있음
Queue 기능
  • 하단에 내리면 있음
Bindings 기능
  • Exchanges 에서 생성한 Exchange를 누르면 Binding 가능

pom 의존성 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit-test</artifactId>
    <scope>test</scope>
</dependency>

yml 설정

spring:
  rabbitmq:
    username: guest
    password: guest
    host: 133.186.241.167
    port: 5672

Config 설정

public class RabbitConfig {
    private static final String EXCHANGE_NAME = "sample.exchange";
    private static final String QUEUE_NAME = "sample.queue";
    private static final String ROUTING_KEY = "sample.routing.key";


    @Bean
    DirectExchange exchange() {
        return new DirectExchange(EXCHANGE_NAME);
    }

    @Bean
    Queue orderQueue() {
        return new Queue(QUEUE_NAME);
    }

    @Bean
    Binding orderBinding(Queue orderQueue, DirectExchange exchange) {
        return BindingBuilder.bind(orderQueue).to(exchange).with(ROUTING_KEY);
    }

    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }
}

RabbitMQ 설정

 private static final String EXCHANGE_NAME = "sample.exchange";

    @Autowired
    RabbitTemplate rabbitTemplate;
    
    @GetMapping("/sample/queue")
    public String samplePublish() {
        rabbitTemplate.convertAndSend(EXCHANGE_NAME, "sample.routing.key", "Log Test");
        return "Hello Rabbit!";
    }

Listener 설정

public class SampleListener {
	private static final Logger log = LoggerFactory.getLogger(SampleListener.class);

    RabbitTemplate rabbitTemplate;

    @RabbitListener(queues = "sample.queue")
    public void processPayment(String message) {
        log.info("Listen" + message);
    }
}
  • Producer (convertAndSend): 편지를 우체국에 맡기는 사람
  • RabbitMQ (Exchange + Queue): 편지를 분류하고 목적지로 전달하는 우체국
  • Consumer (Listener): 편지를 받아 읽고 행동하는 사람

0개의 댓글