RabbitMQ용 Amazon MQ 모범 사례 - Amazon MQ

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

RabbitMQ용 Amazon MQ 모범 사례

이 단원을 참조하여 Amazon MQ에서 RabbitMQ 브로커를 이용할 때 성능을 극대화하고 처리량 비용을 최소화할 수 있는 방법을 신속히 찾으세요.

중요

현재 Amazon MQ는 RabbitMQ 3.9.x에 도입된 스트림 또는 구조화된 로그인 JSON 사용을 지원하지 않습니다.

중요

RabbitMQ용 Amazon MQ는 “게스트”라는 사용자 이름을 지원하지 않으며, 새 브로커를 생성할 때 기본 게스트 계정을 삭제합니다. 또한 Amazon MQ는 고객이 생성한 “게스트”라는 계정을 정기적으로 삭제합니다.

자동 마이너 버전 업그레이드 켜기

최신 브로커 버전 보안 및 버그 수정, 성능 개선 사용. Amazon MQ의 자동 마이너 버전 업그레이드를 활성화하여 최신 패치 버전으로의 업그레이드를 관리할 수 있습니다.

최상의 처리량을 위해 올바른 브로커 인스턴스 유형을 선택하십시오.

브로커 인스턴스 유형의 메시지 처리량은 애플리케이션 사용 사례에 따라 다릅니다. 와 같은 작은 브로커 인스턴스 유형은 애플리케이션 성능을 테스트하는 용도로만 t3.micro 사용해야 합니다. 프로덕션 환경에서 대형 인스턴스를 사용하기 전에 이러한 마이크로 인스턴스를 사용하면 애플리케이션 성능을 개선하고 개발 비용을 절감할 수 있습니다. 인스턴스 유형 이상에서는 m5.large 고가용성과 메시지 내구성을 위해 클러스터 배포를 사용할 수 있습니다. 더 큰 브로커 인스턴스 유형은 프로덕션 수준의 클라이언트 및 대기열, 높은 처리량, 메모리 내 메시지 및 중복 메시지를 처리할 수 있습니다. 올바른 인스턴스 유형을 선택하는 방법에 대한 자세한 내용은 크기 조정 가이드라인을 참조하십시오.

여러 채널 사용

연결 이탈을 방지하려면 단일 연결에서 여러 채널을 사용하세요. 애플리케이션은 1:1 연결 대 채널 비율을 피해야 합니다. 프로세스당 연결 하나, 스레드당 채널 하나를 사용하는 것이 좋습니다. 채널 누수를 방지하려면 과도한 채널 사용을 피하세요.

지연 대기열 활성화

대량의 메시지를 처리하는 매우 긴 대기열로 작업하는 경우 지연 대기열을 활성화하면 브로커 성능이 향상될 수 있습니다.

RabbitMQ는 기본적으로 메시지를 메모리에 캐시하며 브로커에 사용 가능한 메모리가 추가로 필요할 때만 메시지를 디스크로 이동합니다. 메모리에서 디스크로 메시지를 이동하면 시간이 걸리고 메시지 처리가 중단됩니다. 지연 큐는 메시지를 최대한 빨리 디스크에 저장하여 메모리에 캐시되는 메시지 수를 줄여 메모리에서 디스크로의 처리 속도를 크게 높입니다.

지연 대기열을 활성화하려면 선언할 때 queue.declare 인수를 설정하거나 RabbitMQ 관리 콘솔을 통해 정책을 구성할 수 있습니다. 다음의 예제에서는 RabbitMQ Java 클라이언트 라이브러리를 사용하여 지연 대기열을 선언하는 방법을 보여줍니다.

Map<String, Object> args = new HashMap<String, Object>(); args.put("x-queue-mode", "lazy"); channel.queueDeclare("myqueue", false, false, false, args);

3.12.13 이상의 모든 Amazon MQ for RabbitMQ 대기열은 기본적으로 지연 대기열로 동작합니다. RabbitMQ용 Amazon MQ의 최신 버전으로 업그레이드하려면 을 참조하십시오. Amazon MQ 브로커 엔진 버전 업그레이드

참고

지연 대기열을 활성화하면 디스크 I/O 작업이 증가할 수 있습니다.

영구 메시지와 내구성이 뛰어난 대기열을 사용하십시오.

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

메시지 지속성을 활성화하려면 대기열을 durable로 선언하고 메시지 전달 모드를 persistent로 설정할 수 있습니다. 다음의 예제에서는 RabbitMQ Java 클라이언트 라이브러리를 사용하여 지속형 대기열을 선언하는 방법을 보여줍니다. AMQP0-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());

대기열을 짧게 유지

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

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

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

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

또한 자동 삭제 및 TTL 정책을 정의하여 리소스 사용량을 사전에 줄이고 소비자의 접근을 NACKs 최소화할 수 있습니다. 브로커에서 메시지를 대기열에 추가하는 작업은 CPU 사용량이 많기 때문에 메시지 수가 많으면 브로커 성능에 영향을 미칠 수 있습니다NACKs.

승인 및 확인 구성

클라이언트 애플리케이션이 메시지의 배달 및 소비에 대한 확인을 브로커에 다시 보내는 것을 소비자 승인이라고 합니다. 마찬가지로 게시자에게 확인을 보내는 프로세스를 게시자 확인이라고 합니다. 게시자 확인을 통해 메시지가 안정적으로 저장되면 애플리케이션에 알릴 수 있습니다. 게시자의 확인이 없으면 브로커가 메모리가 부족하거나 메시지를 처리할 수 없는 경우에도 메시지를 계속 수락할 수 있습니다. 승인 및 확인은 모두 RabbitMQ 브로커를 사용할 때 데이터 안전을 보장하기 위해 꼭 필요합니다.

소비자 배달 승인은 일반적으로 클라이언트 애플리케이션에서 구성합니다. AMQP0-9-1을 사용하는 경우 메서드를 사용하여 메시지를 가져올 때 basic.consume 또는 를 구성하여 승인을 활성화할 수 있습니다. basic.code AMQP0-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); } });
참고

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

미리 가져오기 구성

RabbitMQ 미리 가져오기 값을 사용하여 소비자가 메시지를 소비하는 방식을 최적화할 수 있습니다. RabbitMQ는 채널이 아닌 소비자에게 프리페치 수를 적용하여 AMQP 0-9-1에서 제공하는 채널 프리페치 메커니즘을 구현합니다. 미리 가져오기 값을 사용하여 지정된 시간에 소비자에게 전송되는 메시지 수를 지정합니다. 기본적으로 RabbitMQ는 클라이언트 애플리케이션에 무제한 버퍼 크기를 설정합니다.

RabbitMQ 소비자의 미리 가져오기 수를 설정할 때는 다양한 요소를 고려해야 합니다. 먼저, 소비자의 환경 및 구성을 고려합니다. 소비자는 처리 중인 모든 메시지를 메모리에 유지해야 하므로 미리 가져오기 값이 높으면 소비자의 성능에 부정적인 영향을 줄 수 있으며 경우에 따라 소비자가 모두 함께 중단될 수도 있습니다. 마찬가지로, RabbitMQ 브로커 자체는 보내는 모든 메시지를 소비자 승인을 받을 때까지 메모리에 캐시된 상태로 유지합니다. 미리 가져오기 값이 높으면 소비자의 자동 승인 구성되어 있지 않은 경우 및 소비자가 메시지를 처리하는 데 비교적 오래 걸리는 경우 RabbitMQ 서버의 메모리가 빠르게 부족해질 수 있습니다.

위의 고려 사항에 유의하여 RabbitMQ 브로커나 해당 소비자가 많은 수의 처리되지 않거나 승인되지 않은 메시지로 인해 메모리가 부족해지는 상황을 방지하기 위해 항상 미리 가져오기 값을 설정하는 것이 좋습니다. 대량의 메시지를 처리하도록 브로커를 최적화해야 하는 경우 다양한 미리 가져오기 수로 브로커와 소비자를 테스트하여 소비자가 메시지를 처리하는 데 걸리는 시간에 비해 네트워크 오버헤드가 크게 중요하지 않게 되는 값을 결정할 수 있습니다.

참고
  • 클라이언트 애플리케이션이 소비자에게 메시지 배달을 자동으로 승인하도록 구성한 경우 미리 가져오기 값을 설정해도 아무런 효과가 없습니다.

  • 미리 가져온 메시지가 모두 대기열에서 제거됩니다.

다음 예제에서는 RabbitMQ Java 클라이언트 라이브러리를 사용하여 단일 소비자의 미리 가져오기 값을 10으로 설정하는 방법을 보여줍니다.

ConnectionFactory factory = new ConnectionFactory(); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.basicQos(10, false); QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume("my_queue", false, consumer);
참고

RabbitMQ 자바 클라이언트 라이브러리에서 global 플래그의 기본값은 false로 설정되므로 위의 예제는 간단히 channel.basicQos(10)으로 작성할 수 있습니다.

Celery 구성

Python Celery는 유용한 정보를 찾고 처리하기가 더 어려워질 수 있는 불필요한 메시지를 많이 보냅니다. 노이즈를 줄이고 처리를 더 쉽게 하려면 다음 명령을 입력합니다.

celery -A app_name worker --without-heartbeat --without-gossip --without-mingle

네트워크 실패 자동 복구

RabbitMQ 노드에 대한 클라이언트 연결이 실패할 경우 상당한 가동 중지를 방지하기 위해 자동 네트워크 복구를 항상 활성화하는 것이 좋습니다. RabbitMQ Java 클라이언트 라이브러리는 4.0.0 버전부터 자동 네트워크 복구를 기본적으로 지원합니다.

연결의 I/O 루프에서 처리되지 않은 예외가 발생하거나, 소켓 읽기 작업 시간 초과가 감지되거나, 서버가 하트비트를 놓치는 경우 자동 연결 복구가 트리거됩니다.

클라이언트와 RabbitMQ 노드 간의 초기 연결이 실패하는 경우에는 자동 복구가 트리거되지 않습니다. 연결을 다시 시도하여 초기 연결 실패를 해결하도록 애플리케이션 코드를 작성하는 것이 좋습니다. 다음 예제에서는 RabbitMQ Java 클라이언트 라이브러리를 사용하여 초기 네트워크 실패를 다시 시도하는 방법을 보여 줍니다.

ConnectionFactory factory = new ConnectionFactory(); // enable automatic recovery if using RabbitMQ Java client library prior to version 4.0.0. factory.setAutomaticRecoveryEnabled(true); // configure various connection settings try { Connection conn = factory.newConnection(); } catch (java.net.ConnectException e) { Thread.sleep(5000); // apply retry logic }
참고

애플리케이션에서 Connection.Close 메서드를 사용하여 연결을 종료하면 자동 네트워크 복구가 활성화되거나 트리거되지 않습니다.

RabbitMQ 브로커용 클래식 대기열 v2 활성화

다음과 같은 성능 개선을 위해 브로커 엔진 버전 3.10 및 3.11에서 Classic Queue v2 (CQv2) 를 활성화하는 것이 좋습니다.

  • 메모리 사용량 감소

  • 소비자 제공 개선

  • 소비자가 생산자의 속도를 따라갈 수 있도록 워크로드 처리량 증가

3.12.13 이상의 모든 RabbitMQ용 Amazon MQ 대기열은 기본적으로 사용됩니다. CQv2 RabbitMQ용 Amazon MQ의 최신 버전으로 업그레이드하려면 을 참조하십시오. Amazon MQ 브로커 엔진 버전 업그레이드

에서 CQv1 으로 마이그레이션하는 중 CQv2

사용하려면 CQv2 먼저 classic_mirrored_queue_version 기능 플래그를 활성화해야 합니다. 기능 플래그에 대한 자세한 내용은 기능 플래그를 활성화하는 방법을 참조하세요.

에서 CQv1 로 마이그레이션하려면 새 대기열 정책을 만들거나 정책 키 정의를 로 설정하여 기존 대기열 queue-version 정책을 편집해야 합니다. CQv2 2 정책 적용에 대한 자세한 내용은 을 참조하십시오정책. 대기열 정책을 CQv2 사용하여 활성화하는 방법에 대한 자세한 내용은 RabbitMQ 설명서의 클래식 대기열을 참조하십시오.

마이그레이션을 시작하기 전에 다른 최고 성능 모범 사례를 따르는 것이 좋습니다.

대기열 정책을 사용하는 경우 대기열 정책을 삭제하면 대기열이 다시 으로 다운그레이드됩니다. CQv2 CQv1 RabbitMQ는 디스크에 있는 대기열 표현을 CQv1 변환하므로 CQv2 대기열을 다운그레이드하지 않는 것이 좋습니다. 심도가 높은 대기열의 경우 이 때문에 메모리 사용량이 많고 시간이 오래 걸릴 수 있습니다.