메시지 확인과 내구성
수동 확인을 구현하고 메시지와 대기열을 내구성 있게 만들어 메시지의 안정성을 보장합니다. 소비자 또는 브로커 장애가 발생해도 데이터 손실을 방지합니다.
메시지 확인과 내구성은(는) CoddyKit의 무료 RabbitMQ Messaging & Async Systems 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 RabbitMQ Messaging & Async Systems 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. RabbitMQ Messaging & Async Systems 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Introduction to Reliability
In distributed systems, ensuring messages are processed reliably is paramount. What happens if a server crashes? Or if a message consumer fails mid-processing?
This lesson explores two key mechanisms in RabbitMQ to prevent data loss and ensure reliability: Message Acknowledgements and Durability for both messages and queues.
What are Message Acknowledgements?
When a consumer receives a message, it needs to tell RabbitMQ that it has successfully processed it. This confirmation is called an Acknowledgement (or 'ack').
- Without Acks: If a consumer crashes before processing, the message is lost.
- With Acks: If a consumer crashes, RabbitMQ knows the message wasn't acknowledged and can redeliver it to another consumer.
Automatic vs. Manual Acknowledgements
RabbitMQ supports two modes for acknowledgements:
- Automatic (Auto-ack): RabbitMQ considers a message acknowledged as soon as it's delivered to the consumer. This is simple but risky, as messages can be lost if the consumer crashes immediately after receiving but before processing.
- Manual (Explicit Ack): The consumer explicitly sends an acknowledgement back to RabbitMQ *after* it has successfully processed the message. This is the recommended approach for reliable processing.
Implementing Manual Acknowledgements
Let's see how to implement manual acknowledgements in a Java consumer. We use channel.basicAck() after our message processing logic completes.
Try running this example. The consumer will acknowledge the message after a short delay.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class ConsumerAck {
private final static String QUEUE_NAME = "ack_queue";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// Declare a non-durable queue
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
// Set prefetch count to 1 for fair dispatch (covered in Work Queues)
channel.basicQos(1);
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
try {
Thread.sleep(1000); // Simulate work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
System.out.println(" [x] Done and Acknowledged");
};
// false means manual acknowledgement
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
// Producer to send a message (for testing)
Channel producerChannel = connection.createChannel();
producerChannel.queueDeclare(QUEUE_NAME, false, false, false, null);
producerChannel.basicPublish("", QUEUE_NAME, null, "Hello Ack!".getBytes("UTF-8"));
System.out.println(" [x] Sent 'Hello Ack!'");
}
}Handling Failed Message Processing
What if a consumer fails to process a message? Instead of acknowledging it, you can negatively acknowledge it:
channel.basicNack(deliveryTag, multiple, requeue): Rejects one or more messages.channel.basicReject(deliveryTag, requeue): Rejects a single message.
The requeue parameter is crucial. If true, the message is sent back to the queue for another consumer. If false, it's discarded or sent to a Dead Letter Exchange (DLX), which we'll cover in a later lesson.
What is Message Durability?
Acknowledgements handle consumer failures, but what about the RabbitMQ broker itself? If the server crashes or restarts, what happens to messages in the queues?
Message Durability ensures that messages persist on disk and survive a broker restart. This means critical messages are never lost, even if the RabbitMQ server goes down unexpectedly.
Making Messages Persistent
To make a message durable, you need to mark it as 'persistent' when publishing. This tells RabbitMQ to write the message to disk.
We use MessageProperties.PERSISTENT_TEXT_PLAIN for this.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
public class ProducerPersistent {
private final static String QUEUE_NAME = "persistent_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()) {
// Declare a durable queue first!
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
String message = "Hello Persistent Message!";
channel.basicPublish(
"",
QUEUE_NAME,
MessageProperties.PERSISTENT_TEXT_PLAIN, // Mark message as persistent
message.getBytes("UTF-8")
);
System.out.println(" [x] Sent '" + message + "'");
}
}
}What is Queue Durability?
Just like messages, queues themselves can be durable. If a queue is not durable, it will be lost if the RabbitMQ broker restarts. Any messages inside it (even persistent ones!) will also be lost.
Therefore, for true reliability, both the queue and the messages within it must be durable.
Declaring a Durable Queue
To make a queue durable, you simply set the durable parameter to true when declaring it. This must be done by both the producer and consumer when they declare the queue.
Run this example. It declares a durable queue and sends a persistent message.
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
public class ProducerDurable {
private final static String DURABLE_QUEUE = "my_durable_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()) {
// Declare a durable queue (durable = true)
channel.queueDeclare(
DURABLE_QUEUE,
true, // durable
false, // exclusive
false, // autoDelete
null // arguments
);
String message = "Hello from a durable queue!";
channel.basicPublish(
"",
DURABLE_QUEUE,
MessageProperties.PERSISTENT_TEXT_PLAIN, // Persistent message
message.getBytes("UTF-8")
);
System.out.println(" [x] Sent '" + message + "' to durable queue.");
}
}
}Quick Check on Reliability
To ensure maximum message reliability (messages are not lost even if a consumer or broker fails), which combination of features is generally required?
Recap & Next Steps
You've learned how to make your RabbitMQ messaging more reliable!
- Manual Acknowledgements confirm message processing, preventing loss on consumer failure.
- Message Durability (persistent messages) ensures messages survive broker restarts.
- Queue Durability ensures the queue definition itself survives broker restarts.
By combining these, you can build robust systems where messages are rarely lost. Next, you'll explore advanced routing patterns using different types of exchanges!
자주 묻는 질문
“메시지 확인과 내구성” 강의는 무료인가요?
네 — “메시지 확인과 내구성” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 RabbitMQ Messaging & Async Systems 강의 전체를 잠금 해제할 수 있습니다. RabbitMQ Messaging & Async Systems 강의에는 총 4개의 강의가 포함되어 있습니다.
“메시지 확인과 내구성”에서 뭘 배우나요?
수동 확인을 구현하고 메시지와 대기열을 내구성 있게 만들어 메시지의 안정성을 보장합니다. 소비자 또는 브로커 장애가 발생해도 데이터 손실을 방지합니다. 브라우저에서 직접 실행하는 실습 코드로 RabbitMQ Messaging & Async Systems을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
RabbitMQ Messaging & Async Systems을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 RabbitMQ Messaging & Async Systems은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“메시지 확인과 내구성” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 RabbitMQ Messaging & Async Systems 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 RabbitMQ Messaging & Async Systems 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.