๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
1๏ธโƒฃ Web/Spring

[Web] ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ SpringBoot์™€ Flask์— RabbitMQ ์ ์šฉํ•˜๊ธฐ

by seolhee2750 2023. 4. 2.

๐Ÿ“ RabbitMQ ์„ค์น˜

1๏ธโƒฃ RabbitMQ ๋ฐ Erlang ์„ค์น˜

์„ค์น˜๋Š” ์•„๋ž˜ ์‚ฌ์ดํŠธ๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.

Windows10์— RabbitMQ ๋น ๋ฅด๊ฒŒ ์„ค์น˜ํ•˜๊ธฐ (with Erlang), ๊ทธ๋ฆฌ๊ณ  RabbitMQ management ๋„์šฐ๊ธฐ (tistory.com)

 

Windows10์— RabbitMQ ๋น ๋ฅด๊ฒŒ ์„ค์น˜ํ•˜๊ธฐ (with Erlang), ๊ทธ๋ฆฌ๊ณ  RabbitMQ management ๋„์šฐ๊ธฐ

MSA ํ”„๋กœ์ ํŠธ๋ฅผ ์ค€๋น„ํ•˜๋ฉฐ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ค€๋น„์‚ฌํ•ญ์ด ์žˆ์ง€๋งŒ ๋Š์Šจํ•œ ๊ฒฐํ•ฉ์„ ์œ„ํ•ด MQ (Message Queue) ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ด๋Ÿฐ ๋ฉ”์„ธ์ง• ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ํˆด์ด ์žˆ์ง€๋งŒ RabbitMQ๋ฅผ ์ผ๋‹จ ์‚ฌ์šฉํ•ด๋ณด๋ คํ•œ๋‹ค. ์–ด๋–ป๊ฒŒ ์„ค

oingdaddy.tistory.com

 

2๏ธโƒฃ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •

์œ„ ๊ณผ์ •๋Œ€๋กœ ์ง„ํ–‰ํ•œ ํ›„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.

[RabbitMQ] ๋ฌด์ž‘์ • ์‹œ์ž‘ํ•˜๊ธฐ (1) - ์„ค์น˜ ๋ฐ ์‹คํ–‰ (tistory.com)

 

[RabbitMQ] ๋ฌด์ž‘์ • ์‹œ์ž‘ํ•˜๊ธฐ (1) - ์„ค์น˜ ๋ฐ ์‹คํ–‰

์ด ํฌ์ŠคํŠธ๋Š” Windows10 ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Œ. ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์˜ ํ•˜๋‚˜์ด๋ฉฐ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์— ๋Œ€ํ•œ ์„ค๋ช…์€ [Message Broker๋ž€?] ํฌ์ŠคํŠธ๋ฅผ ์ฐธ์กฐํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค. RabbitMQ๋Š” ์—ฌ๋Ÿฌ ์ธก๋ฉด์—์„œ ์‚ฌ์šฉ๋˜์ง€๋งŒ ํ•„์ž๋Š” Python

heodolf.tistory.com

 

3๏ธโƒฃ ์‹คํ–‰

์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์น˜๋œ RabbitMQ์˜ sbin ๊ฒฝ๋กœ๋กœ ๋“ค์–ด๊ฐ€์„œ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

C:\Program Files\RabbitMQ Server\rabbitmq_server-3.11.11\sbin>rabbitmq-plugins enable rabbitmq_management

 

RabbitMQ์˜ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋Š” 5672์ด๋ฉฐ, RabbitMQ GUI์˜ ๊ธฐ๋ณธ๊ฒฝ๋กœ๋Š” 15672์ด๋ฏ€๋กœ

http://localhost:15672 ๊ฒฝ๋กœ๋กœ GUI์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์„ฑ๊ณต์ ์œผ๋กœ ์„ค์น˜๋˜์—ˆ๋‹ค๋ฉด ์•„๋ž˜ ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ๊ณ , Username๊ณผ Password ๋ชจ๋‘ guest๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4๏ธโƒฃ ์‹คํ–‰ ์‹คํŒจ ์‹œ

์œ„์˜ 1, 2, 3๋ฒˆ ๊ณผ์ •์„ ๋ชจ๋‘ ์ง„ํ–‰ํ•˜์˜€๋Š”๋ฐ GUI๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด

RabbitMQ์™€ Erlang์„ ๋ชจ๋‘ ์‚ญ์ œํ•œ ๋’ค ๋‹ค์‹œ ์„ค์น˜ํ•˜๋ฉด ์ž˜ ์‹คํ–‰๋œ๋‹ค.

(๊ฐ๊ฐ์˜ ํŒŒ์ผ์— ์žˆ๋Š” Uninstall ํŒŒ์ผ์„ ์‚ฌ์šฉํ•  ๊ฒƒ)

 

๐Ÿ’ฅ ์‚ญ์ œ ํ›„ ๋‹ค์‹œ ์„ค์น˜ํ•  ๋•Œ์˜ ์ฃผ์˜์‚ฌํ•ญ

  • RabbitMQ๋Š” Uninstall ํ›„ ํ•ด๋‹น ํด๋”๊นŒ์ง€ ์‚ญ์ œํ•  ๊ฒƒ
  • Erlang์€ Uninstall ํ›„ ๋‚จ์€ ํด๋”๋ฅผ ์‚ญ์ œํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์‹คํ–‰์ค‘์ด๋ผ๋ฉด์„œ ์‚ญ์ œ๋˜์ง€ ์•Š์„ ๊ฒƒ์ž„. ์ด ๋•Œ ๊ทธ๋ƒฅ ๋ƒ…๋‘๊ธฐ
  • Erlang์€ ๋‹ค์‹œ ์„ค์น˜ํ•  ๋•Œ ๋‚จ์€ ํด๋” ๋•Œ๋ฌธ์— ๊ฒฝ๊ณ  ๋ฌธ๊ตฌ๊ฐ€ ๋œฐํ…๋ฐ, ‘๋ฌด์‹œ’ ์„ ํƒํ•˜๊ธฐ

 


๐Ÿ“ SpringBoot RabbitMQ ์ ์šฉ

1๏ธโƒฃ application.properties

# RabbitMQ
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

 

2๏ธโƒฃ build.gradle

// RabbitMQ
implementation 'io.github.fuquanming:fqm-mq-rabbit:1.0.5'
implementation 'jp.spring-boot-reference:functional-template:1.1'

 

3๏ธโƒฃ config ํŒŒ์ผ ์ž‘์„ฑ

Producer ๋ฐ Consumer ๊ตฌํ˜„์— ํ•„์š”ํ•œ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋ณ„๋„๋กœ queue์™€ exchange๋ฅผ ๋งŒ๋“ค์–ด ์ค„ ํ•„์š” ์—†์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

โž• ์•„๋ž˜์—์„œ queue๋Š” java.util์˜ queue ์•„๋‹˜ ์ฃผ์˜

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqConfig {

    @Value("${spring.rabbitmq.host}")
    private String host;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    @Value("${spring.rabbitmq.port}")
    private int port;

    /***
     * Producer
     ***/

    @Bean
    Queue queue() {
        return new Queue("test.queue", false);
    }

    @Bean
    DirectExchange directExchange() {
        return new DirectExchange("test.exchange");
    }

    @Bean
    Binding binding(DirectExchange directExchange, Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("test.key");
    }

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

    /***
     * either Producer, Consumer
     ***/

    @Bean
    ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }

    @Bean
    MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    /***
     * Consumer
     ***/

    @Bean
    SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        final SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(messageConverter());
        return factory;
    }
}

 

4๏ธโƒฃ Producer ๊ตฌํ˜„

import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class Producer {

    private final RabbitTemplate rabbitTemplate;

    // ๋ฉ”์‹œ์ง€ ์ „์†ก
    public void sendMessage(MessageDto messageDto) {
        rabbitTemplate.convertAndSend("test.exchange", "test.key", messageDto);
    }
}

 

5๏ธโƒฃ Consumer ๊ตฌํ˜„

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

@Component
public class Consumer {

    // ๋ฉ”์‹œ์ง€ ๋ฐ›๊ธฐ
    @RabbitListener(queues = "test.queue")
    public void consume(MessageDto messageDto) {
        System.out.println("[ messageTitle ] : " + messageDto.getTitle());
        System.out.println("[ messageContent ] : " + messageDto.getContent());
    }
}

 


๐Ÿ“ ํ…Œ์ŠคํŠธ ๋ฐ ๊ฒฐ๊ณผ ํ™•์ธ

 

1๏ธโƒฃ ๋ฉ”์‹œ์ง€ ์ ์žฌํ•˜๊ธฐ

์œ„์—์„œ ์ž‘์„ฑํ•œ Producer์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์›ํ•˜๋Š” ์„œ๋น„์Šค์—์„œ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,

์šฐ์„  ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด Controller ๋ฉ”์†Œ๋“œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

(Consumer์˜ ๊ฒฝ์šฐ ๋”ฐ๋กœ ํ˜ธ์ถœํ•ด์ฃผ์ง€ ์•Š์•„๋„ ์•Œ์•„์„œ ์ž‘๋™ํ•œ๋‹ค.)

๊ทธ๋ฆฌ๊ณ  ์ผ๋‹จ ๋ฉ”์‹œ์ง€๊ฐ€ ์ž˜ ์ ์žฌ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด

์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋˜ Consumer๋Š” ์ฃผ์„์ฒ˜๋ฆฌํ•œ ํ›„ Spring์„ ์‹คํ–‰์‹œ์ผฐ๊ณ ,

์•„๋ž˜์™€ ๊ฐ™์ด Postman์„ ํ™œ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋ƒˆ๋‹ค.

 

์œ„์™€ ๊ฐ™์ด ์š”์ฒญ์„ ๋ณด๋‚ผ ์‹œ ์•„๋ž˜ ํ™”๋ฉด์ฒ˜๋Ÿผ Queue์— ํ•˜๋‚˜์˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์Œ“์ธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

(Ready์™€ Total์— 1์”ฉ ๊ฐ’์ด ์ถ”๊ฐ€๋œ ๊ฒƒ ํ™•์ธ)

 

2๏ธโƒฃ ๋ฉ”์‹œ์ง€ ๋ฐ›๊ธฐ

์œ„์™€ ๊ฐ™์ด ๋ฉ”์‹œ์ง€๊ฐ€ ์ž˜ ์ ์žฌ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์œผ๋‹ˆ, ๋‹ค์‹œ Consumer์˜ ์ฃผ์„์„ ํ’€์–ด์„œ Spring์„ ์‹คํ–‰์‹œ์ผฐ๋‹ค.

Spring ์‹คํ–‰ ์‹œ ํŠน๋ณ„ํ•œ ์š”์ฒญ ์—†์ด๋„, ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ Consumer๊ฐ€

queue์— ์Œ“์ธ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์™€ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

(์šฐ๋ฆฌ๋Š” ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ฌธ์žฅ์„ ์ž‘์„ฑํ–ˆ์œผ๋ฏ€๋กœ Console ์ฐฝ์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ)

โž• Consumer๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌ ํ•ด๋†“๊ณ  Producer ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ณด๋‚ธ ํ›„, Consumer๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๋Š” ๊ฒƒ๋„  ์ข‹๋‹ค.

 


๐Ÿ“ Flask ์„œ๋ฒ„์™€ RabbitMQ๋กœ ์†Œํ†ต

์œ„์˜ ๊ณผ์ •์€ RabbitMQ๋ฅผ ์ ์šฉํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—

๊ฐ™์€ ์„œ๋ฒ„์—์„œ Producer์™€ Consumer๋ฅผ ๋ชจ๋‘ ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ ์ง„ํ–‰์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” SpringBoot์—์„œ Flask๋กœ ํ†ต์‹ ํ•˜๋Š” ๊ฒƒ์„ ์œ„ํ•ด RabbitMQ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

๋”ฐ๋ผ์„œ Spring API์— Producer๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ๋‘ ๊ฐœ์˜ Flask์—์„œ Consumer๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ํ†ต์‹ ํ–ˆ๋‹ค.

(ํ•œ ๊ฐœ์˜ Producer, ํ•œ ๊ฐœ์˜ exchange, ํ•œ ๊ฐœ์˜ queue, ๋‘ ๊ฐœ์˜ Consumer)

https://velog.io/@sdb016/RabbitMQ-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90

 

Flask์—์„œ Consumer๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ถ€๋ถ„์€ ์•„๋ž˜ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.

Python์—์„œ RabbitMq ์‚ฌ์šฉํ•˜๊ธฐ (1) - RabbitMQ ๊ธฐ๋ณธ ๋™์ž‘ · snowdeer's Code Holic

 

Python์—์„œ RabbitMq ์‚ฌ์šฉํ•˜๊ธฐ (1) - RabbitMQ ๊ธฐ๋ณธ ๋™์ž‘ · snowdeer's Code Holic

Python์—์„œ RabbitMq ์‚ฌ์šฉํ•˜๊ธฐ (1) - RabbitMQ ๊ธฐ๋ณธ ๋™์ž‘ 24 Dec 2021 | Python RabbitMQ RabbitMQ ๊ธฐ๋ณธ ๋™์ž‘ RabbitMQ๋Š” ํ”„๋กœ๊ทธ๋žจ๊ฐ„ ๋ฉ”์‹œ์ง€๋ฅผ ์‰ฝ๊ฒŒ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” Message Queue์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Producer์—์„œ

snowdeer.github.io

 

๐Ÿ’ฅ ํ•˜๋‚˜์˜ Queue์—์„œ ๋‘ ๊ฐœ์˜ Consumer๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ๋•Œ ์ฃผ์˜์‚ฌํ•ญ

prefetch count๋ฅผ 1๋กœ ์„ค์ •ํ•˜๊ธฐ!

 

RabbitMQ์˜ prefetch count์˜ default ๊ฐ’์€ 20์ด๋‹ค.

 

๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ queue์— 40๊ฐœ์˜ ์š”์ฒญ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด,

Consumer1์ด queue์—์„œ 20๊ฐœ์˜ ์š”์ฒญ์„ ๊บผ๋‚ด์™€์„œ Consumer1์˜ ๋ฉ”๋ชจ๋ฆฌ์— ์Œ“๊ณ ,

Consumer2๊ฐ€ ๋‚จ์€ queue์˜ 20๊ฐœ์˜ ์š”์ฒญ์„ ๊บผ๋‚ด์™€์„œ Consumer2์˜ ๋ฉ”๋ชจ๋ฆฌ์— ์Œ“์€ ๋’ค

๊ฐ Consumer๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์Œ“์•„๋‘” ์š”์ฒญ์„ ์ฐจ๋ก€๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด ๋•Œ Consumer๊ฐ€ 3๊ฐœ๋ผ๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

Consumer1๊ณผ Consumer2๋Š” ์‚ฌ์ด์ข‹๊ฒŒ 20๊ฐœ์”ฉ ์š”์ฒญ์„ ๊ฐ€์ ธ๊ฐ€์ง€๋งŒ,

Consumer3๋Š” ๊ณ„์† ์ผ์„ ํ•˜์ง€ ์•Š๊ณ , Consumer1๊ณผ Consumer2๋งŒ ์ผ์„ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋”ฐ๋ผ์„œ prefetch count๋ฅผ 1๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด

Consumer๋“ค์ด ๊ตณ์ด ์ž์‹ ์˜ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฉ”์‹œ์ง€๋ฅผ ์Œ“์•„๋‘๊ณ  ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ ,

๋ฐ”๋กœ๋ฐ”๋กœ Queue์—์„œ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ ๋ชจ๋“  Consumer์— ๋ฉ”์‹œ์ง€๊ฐ€ ๊ณจ๊ณ ๋ฃจ ๋ถ„๋ฐฐ๋  ์ˆ˜ ์žˆ๋‹ค.

 


์ฐธ๊ณ 

๋Œ“๊ธ€