본문 바로가기

대규모 시스템

RabbitMQ 라우팅 키로 구분하여 하나의 큐로 메세지 보내기

DirectExchangeConfig

더보기
package com.example.direct;

import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DirectExchangeConfig {

    @Bean
    public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("direct-exchange");
    }

    @Bean
    public Queue infoQueue() {
        return new Queue("info-queue");
    }

	
    // info-queue 에 라우팅 키 2개 설정
    @Bean
    public Binding bindingInfo() {
        return BindingBuilder.bind(infoQueue()).to(directExchange()).with("info");
    }

    @Bean
    public Binding bindingtest() {
        return BindingBuilder.bind(infoQueue()).to(directExchange()).with("test");
    }

}

 

 

DirectExchangeProducer - 방법 1 (메세지 객체 수동 생성)

더보기
package com.example.direct;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DirectExchangeProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ObjectMapper objectMapper;

	@GetMapping("/send")
    public String sendMessage(@RequestParam String routingKey, @RequestParam String message) {
    
		// RabbitMQ에서 메시지의 메타데이터를 담는 객체입니다. 
        // 이 객체에는 메시지의 헤더, 우선순위, 내용 타입 등 다양한 속성을 설정할 수 있습니다.
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setHeader("routingKey", routingKey);

        // 메시지 객체 생성
        String jsonMessage;
        try {
        
        // JSON 형식으로 변환하는 이유는 RabbitMQ가 메시지를 텍스트 형식으로 전달하기 때문입니다.
            jsonMessage = objectMapper.writeValueAsString(message);
        } catch (JsonProcessingException e) {
            return "Error processing message to JSON: " + e.getMessage();
        }

		// 메시지 본문은 바이트 배열(jsonMessage.getBytes())로 제공되고
        // 메타데이터는 MessageProperties 객체로 제공됩니다.
        Message amqpMessage = new Message(jsonMessage.getBytes(), messageProperties);
        rabbitTemplate.send("direct-exchange", routingKey, amqpMessage);
   }
}

 

 

DirectExchangeProducer - 방법 2

더보기
package com.example.direct;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DirectExchangeProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @GetMapping("/send")
    public String sendMessage(@RequestParam String routingKey, @RequestParam String message) {
    
    	 // 메시지 전송과 함께 헤더 설정
        rabbitTemplate.convertAndSend("direct-exchange", routingKey, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) {
                MessageProperties props = message.getMessageProperties();
                props.setHeader("routingKey", routingKey);
                return message;
            }
        });
        
    }
 	   
}

 

 

DirectExchangeProducer - 방법 3 (2 방법 > 람다식)

더보기
package com.example.direct;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DirectExchangeProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;
 	
    @GetMapping("/send")
    public String sendMessage(@RequestParam String routingKey, @RequestParam String message) {
    
    	rabbitTemplate.convertAndSend("direct-exchange", routingKey, message,
                msg -> {
                    MessageProperties props = msg.getMessageProperties();
                    props.setHeader("routingKey", routingKey);
                    return msg;
                });
    }
}

 

 

DirectExchangeConsumer - 라우팅 구별해서 받는 방법

더보기
package com.example.topic;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class DirectExchangeConsumer {

    /**
     * 라우팅 구별해서 받는 방법
     * @param message
     */
    @RabbitListener(queues = "info-queue")
    public void receiveInfo(Message message) {
        String messageBody = new String(message.getBody());
        String routingKey = (String) message.getMessageProperties().getHeaders().get("routingKey");

        System.out.println(messageBody);
        System.out.println(routingKey);
    }
}

 

send(), convertAndSend() 차이점

  • send() 메서드 : org.springframework.amqp.core.Message 객체를 직접 전송합니다.
    • 메시지 객체: 직접 Message 객체를 생성하고 전송합니다. 이 객체는 메시지 본문과 메시지 속성(MessageProperties)을 포함합니다.
    • 직접 설정: 메시지 본문과 속성을 완전히 수동으로 설정해야 합니다.
    • 유연성: 메시지의 모든 세부 사항을 직접 제어할 수 있습니다.
  • convertAndSend() 메서드 : 객체를 메시지 본문으로 변환하여 전송합니다.
    • 객체 변환: 메시지 본문을 객체로 제공하면, MessageConverter가 이 객체를 적절한 형식(예: JSON, XML)으로 변환합니다.
    • 자동 변환: MessageConverter를 사용하여 객체를 바이트 배열, 문자열 등으로 자동 변환합니다.
    • 편리성: 메시지 본문과 속성을 자동으로 처리하므로 코드가 간결하고 직관적입니다.

'대규모 시스템' 카테고리의 다른 글

RabbitMQ - Listener 구분하기  (0) 2024.08.14
SAGA Pattern  (0) 2024.08.14
Kafka 기본 설정  (0) 2024.08.14
Kafka란?  (0) 2024.08.14
RabbitMQ 기본 설정  (0) 2024.08.14