๐ RabbitMQ ์ค์น
1๏ธโฃ RabbitMQ ๋ฐ Erlang ์ค์น
์ค์น๋ ์๋ ์ฌ์ดํธ๋ฅผ ์ฐธ๊ณ ํ๋ค.
2๏ธโฃ ํ๊ฒฝ๋ณ์ ์ค์
์ ๊ณผ์ ๋๋ก ์งํํ ํ ํ๊ฒฝ ๋ณ์ ์ค์ ์ด ํ์ํ๋ค.
[RabbitMQ] ๋ฌด์์ ์์ํ๊ธฐ (1) - ์ค์น ๋ฐ ์คํ (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
๐ฅ ํ๋์ 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 |
๋๊ธ