참고자료- rabbitMQ공식문서 : 분리된 어플리케이션 (모듈)끼리 데이터를 주고 받는 (통신) 방식
ex. A service <-> B service

즉 동기와 비동기는 응답을 받을 때까지, 기다리냐 안기다리냐의 차이!
=> 이렇게 생각하면, 블로킹이랑 마치 비슷해보이는데 완료여부를 신경쓸지 말지의 차이이다.
| 동기 | 비동기 |
|---|---|
| A가 B의 리턴(값) 계속 확인! 신경! | B의 작업 완료 여부는 노상관 |
| 콜백함수를 같이 주면서 끝나면 알아서 이거 실행해~ |
| 블로킹 | 논블로킹 |
|---|---|
| A -> B 제어권 넘김 | A가 제어권을 가진 상태로 B 호출! |
| A 멈춤 / B 실행 | A 계속 실행 / B 실행 |
| A <- B 제어권을 다시 넘김 | |
| (ex. B 함수 완료 시) |



메시지 브로커가 왜 생긴걸까?
또, 비동기여야만 하는 이유는?
양쪽 모두에게 자유를 주어 받아가고 싶을 때 받아가고 주고 싶을때 줄 수 있도록!! 주는 친구뿐 아니라, 받아가는 친구의 자유도 높여줌. like kakaotalk
즉, 서로의 자유도를 높여주기 위해 비동기 메시지 브로커를 사용한다!
"Hello World!"
보내는 쪽
package com.example.a_module;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
public class Sender {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
String message = String.join(" ", argv);
channel.basicPublish("", "hello", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
}
}
받는 쪽
package com.example.b_module;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.nio.charset.StandardCharsets;
public class Recv {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}
Work Queues
//package com.example.a_module;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
public class NewTask {
private static final String TASK_QUEUE_NAME = "task_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
String message = String.join(" ", argv);
channel.basicPublish("", TASK_QUEUE_NAME,
MessageProperties.PERSISTENT_TEXT_PLAIN,
message.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + message + "'");
}
}
}
//package com.example.b_module;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.nio.charset.StandardCharsets;
public class Worker {
private static final String TASK_QUEUE_NAME = "task_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
final Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
channel.basicQos(1);
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
try {
doWork(message);
} finally {
System.out.println(" [x] Done");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
};
channel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });
}
private static void doWork(String task) {
for (char ch : task.toCharArray()) {
if (ch == '.') {
try {
Thread.sleep(10000);
} catch (InterruptedException _ignored) {
Thread.currentThread().interrupt();
}
}
}
}
}


