0Pricing
RabbitMQ Messaging & Async Systems · 강의

신뢰성을 위한 퍼블리셔 확인

메시지가 성공적으로 수신되고 브로커에서 처리되었는지 확인하도록 퍼블리셔 확인을 구현합니다. 네트워크 또는 브로커 문제에서 복구할 수 있는 신뢰성 높은 생산자를 구축합니다.

신뢰성을 위한 퍼블리셔 확인은(는) CoddyKit의 무료 RabbitMQ Messaging & Async Systems 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 RabbitMQ Messaging & Async Systems 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. RabbitMQ Messaging & Async Systems 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Why Publisher Confirms?

When you send a message to RabbitMQ, how do you know if it actually arrived safely at the broker?

By default, producers send messages without waiting for any explicit confirmation from RabbitMQ. This is fast, but it means messages could be lost due to network issues or broker failures right after being sent.

Publisher Confirms are a mechanism that allows producers to receive acknowledgements (ACKs) from RabbitMQ when messages have been successfully received and processed by the broker.

The Unseen Gap in Delivery

Imagine sending an important order to a processing queue. Without publisher confirms, your application simply 'sends' the message and moves on.

  • What if the network connection drops the message mid-flight?
  • What if the RabbitMQ server crashes moments after receiving, but before persisting, your message?

Without a confirmation, your producer would assume success, potentially leading to data loss or inconsistent states in your system.

How Confirm Mode Works

To use publisher confirms, you enable 'confirm mode' on a channel. Once enabled, every message published on that channel is assigned a unique delivery tag.

  • ACK (Acknowledgement): The broker sends an ACK back to the producer when a message has been successfully received, routed to its queues, and persisted (if durable).
  • NACK (Negative Acknowledgement): The broker sends a NACK if it couldn't process the message (e.g., failed to route, internal error).

This feedback loop closes the 'delivery gap' between producer and broker.

Enabling Confirm Mode

Before publishing messages, you need to tell RabbitMQ that you want to use publisher confirms on your channel. This is a one-time setup for each channel.

Try running this example to see how to enable confirm mode:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class ConfirmSetup {
  public static void main(String[] args) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost"); // Assumes RabbitMQ is running locally
    try (Connection connection = factory.newConnection();
         Channel channel = connection.createChannel()) {

      channel.confirmSelect(); // This line enables confirm mode
      System.out.println("Channel is now in confirm mode.");
      // Further publishing code would go here
    }
  }
}

Synchronous Confirms: `waitForConfirms`

One way to use publisher confirms is synchronously. After publishing one or more messages, the producer can call channel.waitForConfirms() or channel.waitForConfirmsOrDie().

  • This method blocks the producer until all messages published since the last call have been ACKed or NACKed.
  • It's simple to implement but can significantly slow down throughput, as the producer waits for each batch of messages.
  • Ideal for low-volume, critical messages where immediate confirmation is paramount.

Sync Confirm Code Example

This example shows a producer sending a single message and then waiting for its confirmation. If the message isn't confirmed within 5 seconds, it times out.

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class SyncConfirmPublisher {
  private static final String QUEUE_NAME = "sync_confirm_queue";

  public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    try (Connection connection = factory.newConnection();
         Channel channel = connection.createChannel()) {

      channel.queueDeclare(QUEUE_NAME, false, false, false, null);
      channel.confirmSelect(); // Enable confirm mode

      String message = "Hello, reliable world!";
      channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
      System.out.println(" [x] Sent '" + message + "'");

      // Wait for confirmation for up to 5 seconds
      if (channel.waitForConfirms(5000)) {
        System.out.println("Message confirmed by broker!");
      } else {
        System.out.println("Message not confirmed within timeout! It might be lost or delayed.");
      }
    }
  }
}

Asynchronous Confirms: Listeners

For higher throughput, you can use asynchronous publisher confirms. Instead of blocking, you register a ConfirmListener on the channel.

  • The listener has two methods: handleAck() for successful confirms and handleNack() for negative confirms.
  • RabbitMQ delivers ACKs and NACKs to this listener, allowing your producer to continue publishing messages without waiting.
  • This approach requires more complex logic to track unconfirmed messages, but offers superior performance for high-volume publishing.

Async Confirm Code Example

This example demonstrates an asynchronous publisher. It registers a listener to handle ACKs and NACKs without blocking the main thread.

Notice the Thread.sleep() to keep the program alive long enough to receive confirmations.

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class AsyncConfirmPublisher {
  private static final String QUEUE_NAME = "async_confirm_queue";

  public static void main(String[] args) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    try (Connection connection = factory.newConnection();
         Channel channel = connection.createChannel()) {

      channel.queueDeclare(QUEUE_NAME, false, false, false, null);
      channel.confirmSelect(); // Enable confirm mode

      // Store unconfirmed messages by their delivery tag
      ConcurrentNavigableMap<Long, String> outstandingConfirms = new ConcurrentSkipListMap<>();

      channel.addConfirmListener(new ConfirmListener() {
        @Override
        public void handleAck(long deliveryTag, boolean multiple) throws IOException {
          if (multiple) {
            // Remove all messages up to this deliveryTag
            outstandingConfirms.headMap(deliveryTag + 1).clear();
          } else {
            outstandingConfirms.remove(deliveryTag);
          }
          System.out.println(" [x] Message with deliveryTag " + deliveryTag + " ACKed! Remaining: " + outstandingConfirms.size());
        }

        @Override
        public void handleNack(long deliveryTag, boolean multiple) throws IOException {
          String message = outstandingConfirms.get(deliveryTag);
          System.out.println(" [!] Message '" + message + "' (deliveryTag " + deliveryTag + ") NACKed! Re-sending or logging error.");
          // Handle NACK: re-publish, log, etc.
          if (multiple) {
             outstandingConfirms.headMap(deliveryTag + 1).clear();
          } else {
             outstandingConfirms.remove(deliveryTag);
          }
        }
      });

      String message = "Hello, async reliable world!";
      long nextPublishSeqNo = channel.getNextPublishSeqNo();
      outstandingConfirms.put(nextPublishSeqNo, message);
      channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
      System.out.println(" [x] Sent '" + message + "' (deliveryTag: " + nextPublishSeqNo + ")");

      // Keep main thread alive for a moment to receive confirms
      Thread.sleep(2000);
    }
  }
}

Sync vs. Async: Choosing Wisely

The choice between synchronous and asynchronous confirms depends on your application's needs:

  • Synchronous (waitForConfirms):
    • Simpler to implement.
    • Lower throughput, as it blocks.
    • Good for low-volume, highly critical messages where immediate confirmation is essential.
  • Asynchronous (ConfirmListener):
    • More complex implementation (requires tracking unconfirmed messages).
    • Higher throughput, as it doesn't block.
    • Ideal for high-volume message publishing where performance is key.

Confirm Check

You've learned about publisher confirms. Let's see if you can answer this question.

Recap: Reliable Publishing

Congratulations! You've learned how to make your RabbitMQ producers truly reliable using publisher confirms.

  • Publisher confirms ensure that messages sent by a producer are successfully received and processed by the RabbitMQ broker.
  • You enable confirm mode on a channel using channel.confirmSelect().
  • Synchronous confirms (waitForConfirms()) are simple but block, suitable for low volume.
  • Asynchronous confirms (addConfirmListener()) provide higher throughput for high-volume scenarios, requiring more complex tracking of messages.

By implementing publisher confirms, you can build robust systems that minimize message loss and ensure critical data integrity.

자주 묻는 질문

“신뢰성을 위한 퍼블리셔 확인” 강의는 무료인가요?

네 — “신뢰성을 위한 퍼블리셔 확인” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 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개 중 2번째 강의입니다.

“신뢰성을 위한 퍼블리셔 확인” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 RabbitMQ Messaging & Async Systems 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 RabbitMQ Messaging & Async Systems 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 영속 메시지와 대기열
  2. 신뢰성을 위한 퍼블리셔 확인
  3. 소비자 확인 및 재큐잉
  4. 트랜잭션과 발행자 확인 비교
← RabbitMQ Messaging & Async Systems(으)로 돌아가기