RabbitMQ용 Amazon MQ의 메시지 내구성 및 안정성 모범 사례 - Amazon MQ

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

RabbitMQ용 Amazon MQ의 메시지 내구성 및 안정성 모범 사례

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

1단계: 영구 메시지 및 내구성 있는 대기열 사용

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

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

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

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

import com.rabbitmq.client.MessageProperties; channel.basicPublish("", "my_queue", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

2단계: 게시자 확인 및 소비자 전달 승인 구성

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

마찬가지로 클라이언트 애플리케이션에서 메시지 전송 및 사용에 대한 확인을 브로커에게 다시 보내는 것을 소비자 전송 승인이라고 합니다. 확인 및 승인은 모두 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); } });
참고

승인되지 않은 메시지는 메모리에 캐시되어야 합니다. 클라이언트 애플리케이션의 미리 가져오기 설정을 구성하여 소비자가 미리 가져오는 메시지 수를 제한할 수 있습니다.

소비자가 전송을 확인하지 않는 경우를 감지하도록 consumer_timeout을 구성할 수 있습니다. 소비자가 제한 시간 값 내에 확인을 보내지 않으면 채널이 닫히고 PRECONDITION_FAILED를 수신하게 됩니다. 오류를 진단하려면 UpdateConfiguration API를 사용하여 consumer_timeout 값을 늘리세요.

3단계: 대기열을 짧게 유지

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

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

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

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

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