[RabbitMQ] Publisher Confirm 개념 및 Java에서 Publish Confirm 설정 방법

뿌이·2024년 9월 23일
0

RabbitMQ

목록 보기
2/2
post-thumbnail

RabbitMQ 시스템 흐름

producer(송신자, 주로 Java기반의 서버) -> broker-> queue -> consumer(수신자, 주로 worker서버 라는 이름으로 불림)

Publisher Confirm 이란

Publisher Confirm은 RabbitMQ에서 메시지가 브로커에 성공적으로 도착했는지를 송신자(Producer)에게 확인해주는 기능입니다. 이를 통해 Producer는 메시지가 브로커에 안전하게 저장되었는지 알 수 있고, 만약 메시지가 도착하지 않았거나 문제가 발생했을 경우 재전송할 수 있는 기회를 갖게 됩니다.

기본적으로 RabbitMQ는 메시지를 브로커에 보내고 나면 송신자에게 별도의 응답을 보내지 않기 때문에, 네트워크 문제나 브로커에서의 장애로 인해 메시지가 유실될 가능성이 있습니다. Publisher Confirm을 사용하면 이러한 상황을 방지할 수 있습니다.

Publisher Confirm의 동작 방식

  1. Producer가 메시지를 브로커에 보냅니다.
  2. Broker는 메시지가 큐에 정상적으로 저장되었는지 확인한 후, 송신자에게 성공(ack) 또는 실패(nack) 응답을 보냅니다.
  3. Producer는 이 응답을 통해 메시지가 성공적으로 전달되었는지 확인할 수 있습니다. 실패 응답(nack)을 받으면 Producer는 메시지를 재전송하는 등의 처리를 할 수 있습니다.

Publisher Confirm 설정방법

1. Java에서 Publisher Confirm 사용하기

Java에서는 RabbitMQ의 Channel을 "confirm mode"로 설정하여 Publisher Confirm 기능을 사용할 수 있습니다.

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

public class RabbitMQPublisherConfirmExample {
    private final static String QUEUE_NAME = "confirm_test_queue";

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

            // 큐 선언 (durable 큐로 설정)
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);

            // 채널을 confirm mode로 전환
            channel.confirmSelect();

            String message = "Hello RabbitMQ with Publisher Confirm!";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

            // 메시지가 성공적으로 브로커에 도달했는지 확인
            if (channel.waitForConfirms()) {
                System.out.println("Message successfully confirmed by RabbitMQ!");
            } else {
                System.out.println("Message could not be confirmed. Possible message loss.");
            }
        }
    }
}

주요 코드 설명:

channel.confirmSelect(): 채널을 confirm 모드로 전환합니다. 이를 통해 메시지가 성공적으로 브로커에 도착했는지 확인할 수 있습니다.
channel.basicPublish(): 메시지를 브로커로 전송합니다.
channel.waitForConfirms(): 이 메서드는 메시지가 브로커에 정상적으로 도착했는지 기다립니다. 성공하면 true, 실패하면 false를 반환합니다.

2. 비동기 Publisher Confirm

비동기 방식으로 Publisher Confirm을 사용할 수도 있습니다. 이 방식은 다수의 메시지를 보내는 환경에서 더 효율적일 수 있습니다.

자바는 기본적으로 동기적으로 작동하는 언어이지만, 비동기적인 프로그래밍을 지원합니다. 특히 멀티스레딩비동기 API(CompletableFuture, 자바 8에서 도입된 비동기 API)를 통해 자바에서도 비동기 작업을 수행할 수 있습니다.

RabbitMQ에서도 자바로 비동기 Publisher Confirm을 사용할 수 있으며, 이를 위해 RabbitMQ Java 클라이언트가 비동기적인 ConfirmListener를 제공합니다. 이를 통해 자바에서도 메시지를 비동기적으로 확인하고 처리할 수 있습니다.

비동기 프로그래밍과 자바의 관계

동기적(Synchronous): 메서드 호출이 완료될 때까지 호출한 쪽에서 대기하는 방식입니다. 즉, 한 작업이 완료되기 전까지 다음 작업으로 넘어가지 않습니다.
비동기적(Asynchronous): 작업을 시작한 후 바로 다음 작업을 진행할 수 있으며, 결과는 나중에 처리됩니다. 자바에서도 멀티스레딩이나 콜백을 사용해 비동기적인 작업을 수행할 수 있습니다.

RabbitMQ에서 비동기 Publisher Confirm

비동기 Publisher Confirm은 RabbitMQ에서 메시지를 전송한 후, ConfirmListener를 통해 RabbitMQ 브로커로부터 메시지 전송 성공(ack) 또는 실패(nack)에 대한 알림을 비동기적으로 받는 방식입니다. 자바에서도 이 기능을 쉽게 사용할 수 있습니다.

자바에서 비동기 Publisher Confirm 구현 예시

import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Channel;

public class AsyncPublisherConfirm {
    public static void main(String[] args) throws Exception {
        // RabbitMQ에 연결 및 채널 생성 (생략)

        // 채널을 confirm mode로 전환
        channel.confirmSelect();

        // 비동기 Confirm Listener 추가
        channel.addConfirmListener(new ConfirmListener() {
            public void handleAck(long deliveryTag, boolean multiple) {
                System.out.println("Message confirmed: " + deliveryTag);
            }

            public void handleNack(long deliveryTag, boolean multiple) {
                System.out.println("Message not confirmed: " + deliveryTag);
            }
        });

        // 메시지 전송
        String message = "Message with async confirm";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

        // 메시지가 확인되는 동안 다른 작업을 수행할 수 있음
    }
}

주요 코드 설명:

channel.addConfirmListener(): 비동기로 Publisher Confirm을 처리하기 위해 ConfirmListener를 등록합니다.
handleAck(): 메시지가 성공적으로 전달되었을 때 호출됩니다.
handleNack(): 메시지 전송에 실패했을 때 호출됩니다. 실패한 메시지를 처리할 수 있습니다(재전송 등).

Publisher Confirm의 장점

메시지 신뢰성 보장: 메시지가 브로커에 성공적으로 도달했는지 확인할 수 있어, 메시지 유실 방지.
효율성: 비동기 Confirm을 사용할 경우, 메시지 전송 후 대기하지 않고도 다른 작업을 진행할 수 있습니다.
대용량 처리: 다수의 메시지를 전송할 때도 효율적으로 확인할 수 있어 대용량 메시지 처리에도 적합합니다.

Publisher Confirm과 Transaction 비교

Publisher Confirm: 비동기로 처리되기 때문에 성능이 우수하고 대용량 메시지 처리에 적합합니다.
Transaction 모드: 메시지의 전송을 트랜잭션으로 묶어 처리하므로, 더 강력한 보장을 제공하지만 성능이 낮습니다. Publisher Confirm이 더 가벼운 방식으로 자주 사용됩니다.

결론

Publisher Confirm은 RabbitMQ에서 메시지 유실을 방지하고 메시지가 안전하게 브로커에 도달했는지 확인하는 데 유용한 기능입니다. Producer는 이를 통해 전송한 메시지가 손실되지 않도록 안전하게 관리할 수 있으며, 특히 대용량 메시지 처리 환경에서 성능과 신뢰성을 동시에 보장할 수 있습니다.

profile
기록이 쌓이면 지식이 된다.

0개의 댓글