簡體   English   中英

並行輪詢AWS SQS標准隊列-消息處理太慢

[英]Parallel polling of the AWS SQS standard queue - Message processing is too slow

我有一個模塊,它使用ReceiveMessageRequest在指定的時間間隔一次以一條消息輪詢AWS SQS隊列。 以下是方法:

public static ReceiveMessageResult receiveMessageFromQueue() {

    String targetedQueueUrl = sqsClient.getQueueUrl("myAWSqueueName").getQueueUrl();
    ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(targetedQueueUrl)
            .withWaitTimeSeconds(10).withMaxNumberOfMessages(1);
    return sqsClient.receiveMessage(receiveMessageRequest);
}

一旦收到並處理了一條消息,便使用DeleteMessageResult從隊列中將其刪除。

public static DeleteMessageResult deleteMessageFromQueue(String receiptHandle) {

    log.info("Deleting Message with receipt handle - [{}]", receiptHandle);
    String targetedQueueUrl = sqsClient.getQueueUrl("myAWSqueueName").getQueueUrl();
    return sqsClient.deleteMessage(new DeleteMessageRequest(targetedQueueUrl, receiptHandle));

}

我創建了一個可執行的jar文件,該文件部署在大約40個實例中,並且正在主動輪詢隊列。 我可以看到他們每個人都收到消息。 但是在AWS SQS控制台中,我在“飛行消息”列中只能看到數字0、1、2或3。 為什么即使有40多個不同的使用者都從隊列中接收消息,也為什么呢? 同樣,隊列中可用消息的數量減少得非常緩慢。

以下是隊列的配置參數。

Default Visibility Timeout: 30 seconds
Message Retention Period:   4 days
Maximum Message Size:   256 KB
Receive Message Wait Time:  0 seconds
Messages Available (Visible):   4,776
Delivery Delay: 0 seconds
Messages in Flight (Not Visible):   2
Queue Type: Standard
Messages Delayed:   0
Content-Based Deduplication:    N/A 

為什么即使有多個使用者也無法快速處理郵件? 我是否需要修改任何隊列參數或接收消息/刪除消息請求中的某些內容? 請指教。

更新:

所有EC2實例和SQS都位於同一區域中。 使用者(輪詢隊列的jar文件)作為EC2實例啟動腳本的一部分運行。 而且它有一個計划的任務,每12秒輪詢一次隊列。 在將消息推送到隊列之前,我啟動了2-3個實例。 (當時我們可能有一些已經在運行的實例-這將增加隊列的接收方數量(上限為50)。收到消息后,它將執行一些任務(包括一些數據庫操作,數據分析和計算,報告文件)生成報告並將其上傳到S3等。)大約需要10到12秒。完成后,它將刪除隊列中的消息。下圖是過去1周的SQS指標的屏幕截圖(來自SQS)監控控制台)。

過去1周內目標隊列的SQS指標

我會盡力提供所提供的信息。 有關處理循環邏輯,區域設置和指標的更多詳細信息(請參閱下文)將有助於改善此答案。

我創建了一個可執行的jar文件,該文件部署在大約40個實例中,並且正在主動輪詢隊列。 我可以看到他們每個人都收到消息。 但是在AWS SQS控制台中,我在“飛行消息”列中只能看到數字0、1、2或3。 為什么即使有40多個不同的使用者都從隊列中接收消息,也為什么呢? 同樣,隊列中可用消息的數量減少得非常緩慢。

為什么即使有多個使用者也無法快速處理郵件? 我是否需要修改任何隊列參數或接收消息/刪除消息請求中的某些內容?

您沒有看到與正在處理郵件的主機數量更緊密相關的機上號碼這一事實肯定說明了一個問題-郵件處理速度很快(似乎並非如此)或您的房東沒有做您認為應該做的工作。

通常,從SQS中獲取和刪除單個消息應花費幾毫秒的時間。 如果沒有更多詳細的設置,這應該可以幫助您開始進行故障排除。 其中一些步驟可能看起來很明顯,但是其中每一個步驟都是我所見過的開發人員遇到的現實生活問題的源。

  1. 如果您要為每個receive-process-delete啟動一個新進程,那么這種開銷將使您的速度大大降低。 我假設您沒有這樣做,並且每個主機都在一個進程中運行一個循環
  2. 確認您的處理循環不會令人討厭並重新啟動您(有效地將其轉化為上述情況)。
    • 我假設您還驗證了您的流程在消息處理之外也沒有做很多工作。
  3. 您應該生成一些客戶端指標,以指示SQS請求在每個主機上花費多長時間。
    • Cloudwatch將部分為您執行此操作,但是實際的客戶端指標始終很有用。
    • 建議以下基本指標:(1)接收等待時間,(2)進程等待時間,(3)刪除等待時間,(4)整個消息循環等待時間(5)成功/失敗計數器
  4. 您的EC2實例(進行處理的主機)應與SQS隊列位於同一區域。 如果您正在進行跨區域呼叫,這將影響您的延遲。
    • 確保這些主機具有足夠的CPU /內存資源來進行處理
    • 作為一種優化,我建議每台主機使用更多的線程,而更少的主機-重用客戶端連接並最大程度地利用計算資源總是更好的選擇。
  5. 驗證運行測試時沒有任何中斷或持續問題
  6. 在某些初始化步驟中,僅在應用程序的生命周期內執行一次getQueueUrl 您不需要重復調​​用它,因為它是相同的URL
    • 實際上,這是我在您的代碼中注意到的第一件事 ,但是它落到了這里,因為如果是上述問題,它們將產生更大的影響。
  7. 如果您的消息處理時間非常短(比檢索和刪除消息所需的時間短),那么最終您的主機將花費大部分時間來提取消息。 衡量指標也很重要。
    • 在這種情況下,您可能應該批量提取而不是一次提取。
    • 根據隊列中消息的數量以及運行緩慢的評論,聽起來好像並非如此。
  8. 驗證所有主機實際上都在同一個隊列中(而不是某些beta / gamma版本或您曾經用於測試的舊版本)

進一步說明:

  • 另一個答案表明可見性超時是潛在的原因- 這完全是錯誤的 可見性超時阻塞隊列-它只會影響的消息保持“飛行”之前,另一receiveMessageRequest可以接收消息。
  • 如果您想在出現錯誤/處理器速度較慢時嘗試盡快重新處理消息,則可以考慮減少此開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM