Amazon MQ for RabbitMQ 中訊息耐用性和可靠性的最佳實務 - Amazon MQ

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

Amazon MQ for RabbitMQ 中訊息耐用性和可靠性的最佳實務

在將應用程式移至生產環境之前,請完成下列最佳實務,以防止訊息遺失和資源過度使用。

步驟 1:使用持久性訊息和持久性佇列

持續性訊息有助於防止代理程式當機或重新啟動時資料遺失。持續性訊息會在送達磁碟時立即寫入。然而,與延遲佇列不同,除非代理程式需要更多記憶體,否則持續性訊息會在記憶體和磁碟中快取。在需要更多記憶體的情況下,訊息由管理將訊息儲存到磁碟的 RabbitMQ 代理程式機制從記憶體中刪除,通常稱為持續性層

若要啟用訊息持續性,您可以將佇列宣告為 durable,並將訊息傳遞模式設定為 persistent。以下範例示範如何使用 RabbitMQ Java 用戶端程式庫宣告耐久的佇列。使用 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:設定發佈者確認和消費者交付確認

確認訊息已傳送至代理程式的程序稱為發佈者確認。發佈者確認讓應用程式知道訊息何時可靠地存放。發佈者確認也有助於控制存放在代理程式的訊息速率。如果沒有發佈者確認,則無法確認訊息已成功處理,而且您的代理程式可能會捨棄無法處理的訊息。

同樣地,當用戶端應用程式將訊息的交付確認和取用傳回給代理程式時,稱為消費者交付確認。確認和確認對於確保使用 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:讓佇列保持簡短

在叢集部署中,具有大量訊息的佇列可能會導致資源過度使用。當代理程式過度使用時,重新啟動 Amazon MQ for RabbitMQ 代理程式可能會導致效能進一步降低。若已重新啟動,過度使用的代理程式可能會在 REBOOT_IN_PROGRESS 狀態中變得沒有回應。

維護時段期間,Amazon MQ 會一次執行一個節點的所有維護工作,以確保代理程式維持運作狀態。因此,佇列可能需要在每個節點繼續操作時進行同步處理。在同步期間,需要複寫到鏡像的訊息會從對應的 Amazon Elastic Block Store (Amazon EBS) 磁碟區載入記憶體中,以便分批處理。分批處理訊息可讓佇列更快速地同步處理。

如果佇列保持簡短且訊息很小,則佇列會成功同步處理並繼續如預期般操作。不過,如果批次中的資料量接近節點的記憶體限制,節點就會引發高記憶體警示,暫停佇列同步。您可比較 RabbitMemUsedRabbitMqMemLimit CloudWatch 中的代理程式節點指標,以確認記憶體使用量。直到取用或刪除訊息或減少批次中的訊息數目,才能完成同步處理。

如果叢集部署暫停佇列同步處理,建議您取用或刪除訊息,以減少佇列中的訊息數目。一旦佇列深度減少且佇列同步完成,代理程式狀態就會變更為 RUNNING。若要解決暫停的佇列同步,您也可套用政策以降低佇列同步處理批次大小

您也可以定義自動刪除和 TTL 政策,以主動減少資源用量,並將消費者NACKs 保持在最低限度。在代理程式上重新排入佇列訊息是 CPU 密集型,因此大量 NACKs 可能會影響代理程式效能。