๐ RabbitMQ ์ค์น
1๏ธโฃ RabbitMQ ๋ฐ Erlang ์ค์น
์ค์น๋ ์๋ ์ฌ์ดํธ๋ฅผ ์ฐธ๊ณ ํ๋ค.
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)
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์ ๋ฉ์์ง๊ฐ ๊ณจ๊ณ ๋ฃจ ๋ถ๋ฐฐ๋ ์ ์๋ค.
์ฐธ๊ณ
'1๏ธโฃ Web > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Web] RabbitMQ๊ฐ ํ์ํ ์ด์ (feat. MSA) (0) | 2023.04.02 |
---|---|
[SpringBoot] Spring ๋น๋ํ๊ณ ์คํํ๋ ๋ฐฉ๋ฒ (0) | 2022.04.26 |
[SpringBoot] spring-boot-devtools ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ ๋ฐฉ๋ฒ (0) | 2022.04.26 |
๋๊ธ