2017-06-20 84 views
1

我正在尋找與我正在使用產品進行的架構設計決策有關的幫助。AWS SQS異步排隊模式(請求/響應)

我們已經有多個生產者(由API網關調用到Lambda中發起)將消息放入SQS隊列(請求隊列)中。可以有多個同時調用,所以會有多個並行運行的Lambda實例。

然後我們有消費者(讓我們說20個EC2實例)對SQS進行長時間輪詢以處理消息。他們需要大約30-45秒來處理每條消息。

然後,我會理想地將響應發回給發出請求的生產者 - 這是我與SQS一起努力的部分。理論上我會有一個單獨的響應隊列,最初的Lambda生產者將會消耗這些響應隊列,但似乎沒有辦法選擇具體的相關響應。也就是說,每個Lambda函數可能會選擇另一個函數的響應。我正在尋找類似於此設計模式的東西:http://soapatterns.org/design_patterns/asynchronous_queuing

我可以看到的唯一選擇是爲每個Lambda API調用創建一個新的SQS Response隊列,並在其消息中傳遞消息中的ARN對此的迴應,但我無法想象這非常有效 - 尤其是當每分鐘有數百條消息時?我錯過了明顯的東西嗎?

我想唯一的另一種選擇是設置一個更大的消息代理(例如RabbitMQ/ApacheMQ)環境,但是我希望儘可能避免這種情況。

謝謝!

回答

1

是的,你可以使用RabbitMQ來獲得更多的「rpc」隊列模式。

但是,如果您希望保留在AWS內,請嘗試使用除SQS以外的其他內容作爲響應。

相反,您可以使用S3作爲響應。當您的生產者將該項目放入SQS時,在消息中包含響應的S3目標。當您的消費者完成任務時,將響應放置在所需的S3位置。

然後您可以檢查S3的響應。

更新

您可以實現使用Redis的一個RPC般的消息隊列。

https://github.com/ServiceStack/ServiceStack/wiki/Messaging-and-redis

然後,您可以使用AWS ElastiCache爲您的Redis集羣。這將完全取代SQS的使用。

+0

嗨馬特,謝謝你的迴應。我不確定S3如何在這種情況下工作 - 生產者將不得不輪詢以檢查S3響應文件是否存在? S3上沒有長時間輪詢我可以找到,所以即使我每秒都檢查一次,它看起來效率很低,特別是每分鐘可能有數百個請求。 –

+0

正確,你將不得不輪詢S3。 AWS無法向您的Lambda函數反饋迴應已準備就緒。所以你有4個選項:(a)使用SQS,每個請求一個隊列,(b)使用SQS,共享結果隊列(這兩個選項都不是理想的),(c)輪詢某個結果的東西(S3,數據庫等) 。),或(d)使用非AWS服務。 –

+0

再次感謝,我感謝您在此問題上的明確和專業知識。我之前沒有使用過Redis,但是你的鏈接(特別是Request + Reply MQ Pattern)聽起來像是一個很好的選擇,所以我會調查一下,看看它是否適用於我們的環境。再次感謝。 –

0

爲了晚會來臨,但我想我可能會在我想達到的目標中找到一些幫助,@MattHouser @Zaheer Ally,或者給某個在相關問題上工作的人提供一個想法。

我正面臨類似的挑戰。我有一個API,根據客戶的請求,需要與多個外部API進行通信並收集(延遲)結果。

由於我的PHP API是同步的,它只能按順序執行這些請求。所以,我正在考慮使用請求隊列,其中生產者(API)將發送消息。然後,多個工作人員會使用這些消息,每個人都執行這些外部API調用之一。

爲了得到結果,生產者將創建一個臨時響應隊列,其名稱標識符將嵌入到發送給工人的消息中。因此,每個工人都會在這個臨時隊列上「公佈」他的結果。

與此同時,生產者將繼續輪詢臨時隊列,直到他收到預期的消息數量。最後,他會刪除隊列並將收集到的結果發送回客戶端。

雖然看起來是正確的,但我覺得這個解決方案根本不夠優雅,容易出現故障,對於在PHP中實現的典型HTTP請求 - 響應週期來說,這種方法絕對沒有效率。

有什麼想法?

0

另一種選擇是使用Redis的'pub/sub機制異步通知您的lambda後端工作已完成。您可以將AWS's Elasticache for Redis用於全AWS管理的解決方案。您的lambda函數會爲每個請求生成一個UUID,將其用作訂閱的通道名稱,並在SQS消息中傳遞它,然後當工作完成後,後端工作人員會向該通道發佈通知。

我正面臨同樣的問題,所以I tried it out,它確實有效。是否值得僅僅投票S3就是另一個問題。您必須將lambda函數配置爲run inside your VPC,以便他們可以訪問您的Redis。無論如何,我將不得不這樣做,因爲我希望工作人員(在我的情況下也是lambda函數)能夠訪問我的Elasticsearch和RDS。但是有一些注意事項:最重要的是,您需要使用帶有NAT網關(或您自己的NAT實例)的私有子網,以便能夠訪問Internet和AWS託管服務(包括SQS)。我只是偶然發現

aws diagram

的另一件事是,通過API網關目前cannot take longer than 29 seconds,而這種要求不能得到提高AWS。您提到您的工作需要30秒或更長時間,因此無論如何,這可能會成爲您使用API​​ Gateway和Lambda的不二人選。