

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# RabbitMQ용 Amazon MQ의 메시지 내구성 및 신뢰성 모범 사례
<a name="best-practices-message-reliability"></a>

 애플리케이션을 프로덕션으로 이동하기 전에 메시지 손실 및 리소스 과다 활용을 방지하기 위한 다음 모범 사례를 완료하세요.

## 1단계: 영구 메시지 및 지속형 대기열 사용
<a name="use-persistent-messages-durable-queues"></a>

 영구 메시지는 브로커가 중단되거나 다시 시작하는 상황에서 데이터 지속성을 보호할 수 있습니다. 영구 메시지는 도착하는 즉시 디스크에 기록됩니다. 그러나 지연 대기열과 달리 영구 메시지는 브로커에 추가 메모리가 필요하지 않는 한 메모리와 디스크 모두에 캐시됩니다. 추가 메모리가 필요한 경우 메시지는 디스크에 대한 메시지 저장을 관리하는 RabbitMQ 브로커 메커니즘(일반적으로 *지속성 계층*이라고 함)에 의해 메모리에서 제거됩니다.

메시지 지속성을 활성화하려면 대기열을 `durable`로 선언하고 메시지 전달 모드를 `persistent`로 설정할 수 있습니다. 다음의 예제에서는 [RabbitMQ Java 클라이언트 라이브러리](https://www.rabbitmq.com/java-client.html)를 사용하여 지속형 대기열을 선언하는 방법을 보여줍니다. AMQP 0-9-1로 작업할 때 전송 모드를 "2"로 설정하여 메시지를 영구 메시지로 표시할 수 있습니다.

```
boolean durable = true;
channel.queueDeclare("my_queue", durable, false, false, null);
```

 대기열을 지속형으로 구성하면 다음 예제와 같이 `MessageProperties`를 `PERSISTENT_TEXT_PLAIN`으로 설정하여 영구 메시지를 대기열에 보낼 수 있습니다.

```
import com.rabbitmq.client.MessageProperties;

channel.basicPublish("", "my_queue",
            MessageProperties.PERSISTENT_TEXT_PLAIN,
            message.getBytes());
```

## 2단계: 게시자 확인 및 소비자 전송 승인 구성
<a name="configure-confirmation-acknowledgement"></a>

 메시지가 브로커에 전송되었는지 확인하는 프로세스를 *게시자 확인*이라고 합니다. 게시자 확인은 메시지가 안정적으로 저장된 시점을 애플리케이션에 알립니다. 게시자 확인은 브로커에 저장되는 메시지의 속도를 제어하는 데도 도움이 됩니다. 게시자 확인이 없으면 메시지가 성공적으로 처리되었는지 확인할 수 없으며, 브로커가 처리할 수 없는 메시지를 삭제할 수 있습니다.

 마찬가지로 클라이언트 애플리케이션에서 메시지 전송 및 사용에 대한 확인을 브로커에게 다시 보내는 것을 *소비자 전송 승인*이라고 합니다. 확인 및 승인은 모두 RabbitMQ 브로커를 사용할 때 데이터 안전을 보장하기 위해 꼭 필요합니다.

 소비자 배달 승인은 일반적으로 클라이언트 애플리케이션에서 구성합니다. AMQP 0-9-1을 사용할 경우 `basic.consume` 메서드를 구성하여 승인을 활성화할 수 있습니다. AMQP 0-9-1 클라이언트는 `confirm.select` 메서드를 전송하여 게시자 확인을 구성할 수도 있습니다.

 일반적으로 배달 승인은 채널에서 활성화합니다. 예를 들어 RabbitMQ Java 클라이언트 라이브러리를 사용할 때 다음 예제와 같이 `Channel#basicAck`를 사용하여 간단한 `basic.ack` 긍정 승인을 설정할 수 있습니다.

```
// this example assumes an existing channel instance

boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "a-consumer-tag",
     new DefaultConsumer(channel) {
         @Override
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body)
             throws IOException
         {
             long deliveryTag = envelope.getDeliveryTag();
             // positively acknowledge a single delivery, the message will
             // be discarded
             channel.basicAck(deliveryTag, false);
         }
     });
```

**참고**  
 승인되지 않은 메시지는 메모리에 캐시되어야 합니다. 클라이언트 애플리케이션의 [미리 가져오기](best-practices-performance.md#configure-prefetching) 설정을 구성하여 소비자가 미리 가져오는 메시지 수를 제한할 수 있습니다.

 소비자가 전송을 확인하지 않는 경우를 감지하도록 `consumer_timeout`을 구성할 수 있습니다. 소비자가 제한 시간 값 내에 확인을 보내지 않으면 채널이 닫히고 `PRECONDITION_FAILED`를 수신하게 됩니다. 오류를 진단하려면 [UpdateConfiguration](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/configurations-configuration-id.html) API를 사용하여 `consumer_timeout` 값을 늘리세요.

## 3단계: 대기열을 짧게 유지
<a name="keep-queues-short"></a>

클러스터 배포에서 대기열에 메시지 수가 많으면 리소스가 과도하게 사용될 수 있습니다. 브로커가 과도하게 사용되면 RabbitMQ용 Amazon MQ가 재부팅하여 성능이 더욱 저하될 수 있습니다. 재부팅되면 과도하게 사용된 브로커가 `REBOOT_IN_PROGRESS` 상태에서 응답하지 않게 될 수 있습니다.

[유지 관리 기간](amazon-mq-rabbitmq-editing-broker-preferences.md#rabbitmq-edit-current-configuration-console) 중 Amazon MQ는 모든 유지 관리 작업을 한 번에 한 노드에서 수행하여 브로커가 계속 작동하도록 합니다. 따라서 각 노드의 작동이 다시 시작할 때 대기열을 동기화해야 할 수 있습니다. 동기화하는 동안 미러에 복제되어야 하는 메시지는 해당하는 Amazon Elastic Block Store(Amazon EBS) 볼륨에서 메모리로 로드되어 배치로 처리됩니다. 메시지를 배치로 처리하면 대기열을 더 빠르게 동기화할 수 있습니다.

대기열이 짧게 유지되고 메시지가 작으면 대기열이 성공적으로 동기화되고 예상대로 작업이 재개됩니다. 그러나 배치의 데이터 양이 노드의 메모리 한도에 가까워지면 노드에서 고용량 메모리 경보가 발생하여 대기열 동기화가 일시 중지됩니다. 메모리 사용량은 [CloudWatch의 브로커 노드 지표](amazon-mq-accessing-metrics.md) `RabbitMemUsed`와 `RabbitMqMemLimit`를 비교하여 확인할 수 있습니다. 메시지가 사용 또는 삭제되거나 배치의 메시지 수가 줄지 않으면 동기화가 완료될 수 없습니다.

 대기열 동기화가 클러스터 배포를 위해 일시 중지된 경우 메시지를 사용하거나 삭제하여 대기열의 메시지 수를 줄이는 것이 좋습니다. 대기열 깊이가 줄고 대기열 동기화가 완료되면 브로커 상태가 `RUNNING`으로 변경됩니다. 일시 중지된 대기열 동기화를 해결하기 위해 [대기열 동기화 배치 크기를 줄이는](rabbitmq-queue-sync.md) 정책을 적용할 수도 있습니다.

또한 자동 삭제 및 TTL 정책을 정의하여 리소스 사용량을 선제적으로 줄이고 소비자의 NACK을 최소화할 수 있습니다. 브로커에서 메시지를 다시 대기열에 넣는 작업은 CPU를 많이 사용하므로 많은 수의 NACK이 발생하면 브로커 성능에 영향을 줄 수 있습니다.