RabbitMQ - RabbitMQμ λνμ¬
π RabbitMQ - RabbitMQ μ κ΄νμ¬
Redis λ₯Ό 곡λΆνλ©΄μ Redis μ Mesaage Queuing μ 곡λΆνλ€κ° Kafka μ RabbitMQ μ λν΄ μκ² λμλ€. λ΄κ° μΌνκ³ μλ νμ¬μμ Kafka λ₯Ό μ¬μ©νκΈ°μλ μμ€ν λλΉ Learning Curve λ° λ°μ΄ν° μ¬μ©λμ΄ μ κΈ°λ νκ³ RabbitMQ κ° μ‘°κΈλ μ ν©ν΄λ³΄μ¬μ μ 리ν΄λ³΄λ €κ³ νλ€.
π© RabbitMQ λ?
AMQPλ₯Ό ꡬννμ¬ μλ²κ° λ©μΈμ§(λ°μ΄ν°)λ₯Ό μ λ¬ν΄μ£Όλ μ€ν μμ€ λ©μμ§ λΈλ‘컀 μννΈμ¨μ΄ ( λ©μμ§ μ§ν₯ λ―Έλ€μ¨μ΄ )
π AMQP ( Advanced Message Queuing Protocol) λ?
λ©μμ§ μ§ν₯ λ―Έλ€μ¨μ΄λ₯Ό μν κ°λ°©ν νμ€ μμ© κ³μΈ΅ νλ‘ν μ½
π© RabbitMQ ꡬμ±
π 1. Message
- μλ²κ° μ²λ¦¬νκ³ μ νλ λ©μΈμ§(λ°μ΄ν°)
π 2. Producer
- Message λ₯Ό μ‘μ νλ 주체
- Message λ₯Ό Consumer μκ² μ λ¬νκΈ° μν΄ Message λ₯Ό Exchange μ λ°ννλ€.
- Queue μ μ§μ μ κ·Όνμ§ μκ³ , νμ Exchange λ₯Ό ν΅ν΄ μ κ·Όνλ€.
π 3. Exchange
- Producer μκ² μ λ¬λ°μ λ©μΈμ§(λ°μ΄ν°)λ₯Ό Queue μκ² μ λ¬ν΄μ£Όλ Router μν
- Exchange λ Message λ₯Ό μ΄λ€ Queue μ μΆκ°ν μ§, λ²λ €μΌν μ§ λ± κ·μΉμ μν΄ κ²°μ νλ€.
- Exchange μ κ·μΉ : Fanout, Direct, Topic, Headers
π 4. Bindings
- Exchange μ Queue μ κ΄κ³
- Binding κ³Όμ μ΄ μμ΄μΌ Exchange μμ Queue λ‘ λ©μΈμ§(λ°μ΄ν°)κ° μ΄λνλ€.
- ν΅μμ μΌλ‘ Exchange κ° μ΄λ Queue μ Binding ν μ§ μ μν΄μΌνλ€.
π 5. Queues
- Consumer μκ² λ©μΈμ§(λ°μ΄ν°)λ₯Ό μ λ¬νλ μν
- In-Memory or Disk μ Message λ₯Ό 보κ΄
- Queue λ μ΄λ¦μΌλ‘ ꡬλΆλλ€. β» κ°μ μ΄λ¦κ³Ό κ°μ μ€μ μΌλ‘ Queue λ₯Ό μμ±νλ©΄ μλ¬ μμ΄ κΈ°μ‘΄ Queue μ μ°κ²°λμ§λ§, κ°μ μ΄λ¦κ³Ό λ€λ₯Έ μ€μ μΌλ‘ Queue λ₯Ό μμ±νλ €κ³ μλνλ©΄ μλ¬κ° λ°μνλ μ£Όμν΄μΌ νλ€.
π 6. Consumer
- Message λ₯Ό μμ νλ 주체
- Queue μ μ§μ μ κ·Όνμ¬ λ©μΈμ§(λ°μ΄ν°)λ₯Ό κ°μ Έμ¨λ€.
π© Exchange μ’ λ₯
μ’ λ₯ | μ€λͺ | νΉμ§ |
---|---|---|
Direct | Routing Key κ° μ νν μΌμΉνλ Queue μκ² Message μ μ‘ | Unicast / Multicast |
Topic | Routing Key μ ν¨ν΄μ΄ μΌμΉνλ Queue μκ² Message μ μ‘ | Multicast |
Headers | ( Key:Value ) λ‘ μ΄λ£¨μ΄μ§ Header κ° μ κΈ°μ€μΌλ‘ μΌμΉνλ Queue μκ² Message μ μ‘ | Multicast |
Fanout | ν΄λΉ Exchange μ λ±λ‘ λ λͺ¨λ Queue μκ² Message μ μ‘ | Broadcast |
π 1. Direct ( Unicast / 1:1 or 1:N )
- RabbitMQ μμ μ¬μ©λλ Exchange μ Default Option μ΄λ€.
- RabbitMq μμ μμ±λλ Queue κ° μλμΌλ‘ Binding λκ³ , Queue μ μ΄λ¦μ΄ routing key λ‘ μ§μ λλ€.
- νλμ Queue μ μ¬λ¬κ°μ routing key λ₯Ό μ§μ ν μ μλ€. ( Ex. Exchange Type = Direct Example 01 )
- μ¬λ¬κ°μ Queue μ λμΌν routing key λ₯Ό μ§μ ν μ μλ€. ( Ex. Exchange Type = Direct Example 02 )
π 2. Topic ( Multicast / 1:N )
- routing key μ ν¨ν΄μ΄ μΌμΉνλ Queue μ λ©μΈμ§(λ°μ΄ν°)λ₯Ό μ λ¬νλ€.
- Direct λ³΄λ€ μ’ λ μ μ°νκ² μ μν΄μ λ©μΈμ§(λ°μ΄ν°)λ₯Ό μ μ‘ν μ μλ€.
- κ·μΉ
- * : νλμ λ¨μ΄λ₯Ό μλ―Ένλ€.
- # : 0κ° μ΄μμ λ¨μ΄λ₯Ό μλ―Ένλ€.
- μμ
- routing Key : quick.orange.male.rabbit
- λ©μΈμ§(λ°μ΄ν°)λ₯Ό λ°λ Queue κ° μλ€.
- routing Key : quick.orange.fox
- Q1λ§ λ©μΈμ§(λ°μ΄ν°)λ₯Ό λ°λλ€.
- routing Key : lazy.orange.male.rabbit
- Q2λ§ λ©μΈμ§(λ°μ΄ν°)λ₯Ό λ°λλ€.
- routing Key : quick.orange.male.rabbit
π 3. Headers ( Multicast / 1:N )
- key-value λ‘ μ μλ ν€λμ μν΄ λ©μΈμ§λ₯Ό Queue μ μ λ¬νλ λ°©λ².
- Producer κ° μ μνλ Header μ key-value μ Consumer κ° μ μν argument μ key-valueκ° μΌμΉνλ©΄ Binding λλ€.
x-match : all
- Producer κ° μ μνλ Header μ key-value μ Consumer κ° μ μν argument μ key-value κ° μ νν μΌμΉν΄μΌ Binding λλ€.
x-match : any
- Producer κ° μ μνλ Header μ key-value μ Consumer κ° μ μν argument μ key-value μ€ νλλΌλ μΌμΉνλ©΄ Binding λλ€.
π 4. Fanout ( Broadcast / 1:ALL )
- μ¬μ§κ³Ό κ°μ΄ Exchange μμ λ©μΈμ§(λ°μ΄ν°)λ₯Ό κ±°λ₯΄μ§ μκ³ Binding λμ΄ μλ λͺ¨λ Queue μ λ©μΈμ§(λ°μ΄ν°)λ₯Ό μ μ‘νλ€.
π© RabbitMQ & Spring Boot μ°λ
π¨ 1. Pom.xml
1
2
3
4
5
<!-- RabbitMQ Dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
π¨ 2. application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
rabbitmq:
host: localhost // RabbitMQ host ip
port: 5672 // RabbitMQ port
username: guest // RabbitMQ μΉ κ΄λ¦¬ μ½μ μμ΄λ
password: guest // RabbitMQ μΉ κ΄λ¦¬ μ½μ λΉλ°λ²νΈ
queue:
name: sample-queue // μ¬μ©ν queue μ΄λ¦
exchange:
name: sample-exchange // μ¬μ©ν exchange μ΄λ¦
routing:
key: key
π¨ 3. RabbitMqConfig Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import lombok.RequiredArgsConstructor;
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.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;
@RequiredArgsConstructor
@Configuration
public class RabbitMQConfig {
@Va
@Value("${spring.rabbitmq.queue.name}")
private String queueName;
@Value("${spring.rabbitmq.exchange.name}")
private String exchangeName;
@Value("${spring.rabbitmq.routing.key}")
private String routingKey;
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String userName;
@Value("${spring.rabbitmq.password}")
private String password;
// org.springframework.amqp.core.Queue
@Bean
public Queue queue() {
return new Queue(queueName);
}
/**
* μ§μ λ Exchange μ΄λ¦μΌλ‘ Direct Exchange Bean μ μμ±
*/
@Bean
public DirectExchange directExchange() {
return new DirectExchange(exchangeName);
}
/**
* μ£Όμ΄μ§ Queue μ Exchange μ Binding νκ³ Routing Key μ μ΄μ©νμ¬ Binding Bean μμ±
* Exchange μ Queue μ λ±λ‘
**/
@Bean
public Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(routingKey);
}
/**
* RabbitMQ μ°λμ μν ConnectionFactory λΉμ μμ±νμ¬ λ°ν
**/
@Bean
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(this.host);
connectionFactory.setPort(this.port);
connectionFactory.setUsername(this.userName);
connectionFactory.setPassword(this.password);
return connectionFactory;
}
/**
* RabbitTemplate
* ConnectionFactory λ‘ μ°κ²° ν μ€μ μμ
μ μν Template
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
return rabbitTemplate;
}
/**
* μ§λ ¬ν(λ©μΈμ§λ₯Ό JSON μΌλ‘ λ³ννλ Message Converter)
*/
@Bean
public MessageConverter jackson2JsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
π¨ 4. RabbitMqService Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@RequiredArgsConstructor
@Service
public class RabbitMqService {
@Value("${spring.rabbitmq.queue.name}")
private String queueName;
@Value("${spring.rabbitmq.exchange.name}")
private String exchangeName;
@Value("${spring.rabbitmq.routing.key}")
private String routingKey;
private final RabbitTemplate rabbitTemplate;
/**
* 1. Queue λ‘ λ©μΈμ§λ₯Ό λ°ν
* 2. Producer μν -> Direct Exchange μ λ΅
**/
public void sendMessage(MessageDto messageDto) {
log.info("messagge send: {}", messageDto.toString());
this.rabbitTemplate.convertAndSend(exchangeName, routingKey, messageDto);
}
/**
* 1. Queue μμ λ©μΈμ§λ₯Ό ꡬλ
**/
@RabbitListener(queues = "${rabbitmq.queue.name}")
public void receiveMessage(MessageDto messageDto) {
log.info("Received Message : {}", messageDto.toString());
}
}
π¨ 5. RabbitMqService Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequiredArgsConstructor
@RestController
public class RabbitMqController {
private final RabbitMqService rabbitMqService;
@PostMapping("/send/message")
public ResponseEntity<String> sendMessage(
@RequestBody MessageDto messageDto
) {
this.rabbitMqService.sendMessage(messageDto);
return ResponseEntity.ok("Message sent to RabbitMQ");
}
}
μ΄ κΈ°μ¬λ μ μκΆμμ CC BY 4.0 λΌμ΄μΌμ€λ₯Ό λ°λ¦
λλ€.