2014-10-30 127 views
0

因爲一切都失敗了。在向Amazon SQS發佈消息時如何處理錯誤,是否有任何建議/最佳實踐?AWS SQS錯誤處理

我正在運行Amazon .NET SDK並每天發送幾條1000 SQS消息。我沒有注意到出版失敗了,但這可能是任何問題都浮出水面。

不過,我應該如何在下列基本代碼(幾乎是一個簡單的使用從SDK文檔的例子)處理錯誤:

public static string sendSqs(string data) 
{ 
    IAmazonSQS sqs = AWSClientFactory.CreateAmazonSQSClient(RegionEndpoint.EUWest1); 
    SendMessageRequest sendMessageRequest = new SendMessageRequest(); 
    CreateQueueRequest sqsRequest = new CreateQueueRequest(); 
    sqsRequest.QueueName = "mySqsQueue"; 
    CreateQueueResponse createQueueResponse = sqs.CreateQueue(sqsRequest); 
    sendMessageRequest.QueueUrl = createQueueResponse.QueueUrl; 
    sendMessageRequest.MessageBody = data; 
    SendMessageResponse sendMessageresponse = sqs.SendMessage(sendMessageRequest); 
    return sendMessageresponse.MessageId; 
} 

回答

1

你根本不需要做很多你自己的錯誤處理;適用於.NET的AWS開發工具包會在後臺處理瞬時故障的重試。

它會自動重試失敗,如果任何要求:

  • 您的AWS服務的訪問已被節流
  • 請求超時
  • 的HTTP連接失敗

它對多次重試使用指數退避策略。在第一次失敗時,它睡了400毫秒,然後再次嘗試。如果該嘗試失敗,則在再次嘗試之前睡眠1600毫秒。如果失敗,它將會休眠6400毫秒,等等,最多30秒。

當達到重試配置的最大數,SDK將拋出。您可以配置重這樣的最大數量:

var sqsClient = AWSClientFactory.CreateAmazonSQSClient( 
      new AmazonSQSConfig 
      { 
       MaxErrorRetry = 4 // the default is 4. 
      }); 

如果API調用結束投擲,這意味着什麼是真的錯了,像SQS在您所在地區下降了,或者你的請求無效。

來源:The AWS SDK for .NET Source Code on GitHub

+0

如果從甚至在EC2而是通過NAT或代理服務器EC2的或外部打電話到SQS,總有互聯網連接下去,即使SQS仍然可用的可能性。這可能是一個非常難處理的問題,因爲這種類型的問題是首先使用隊列的主要原因。 – JaredHatfield 2015-07-16 02:22:39

1

一(還挺無關),我會建議從分離客戶端發送消息:

public class QueueStuff{ 
private static IAmazonSQS SQS; 

//Get only one of these 
public QueueStuff(){ 
    SQS = AWSClientFactory.CreateAmazonSQSClient(RegionEndpoint.EUWest1); 
} 
//...use SQS elsewhere... 

最後回答你的問題:檢查Common ErrorsSendMessage(在你的情況下)的網頁,趕上相關的異常。你做什麼取決於你的應用程序以及它應該如何處理丟失的消息。一個例子可能是:

public static string sendSqs(string data) 
{ 
    SendMessageRequest sendMessageRequest = new SendMessageRequest(); 
    CreateQueueRequest sqsRequest = new CreateQueueRequest(); 
    sqsRequest.QueueName = "mySqsQueue"; 
    CreateQueueResponse createQueueResponse = sqs.CreateQueue(sqsRequest); 
    sendMessageRequest.QueueUrl = createQueueResponse.QueueUrl; 
    sendMessageRequest.MessageBody = data; 
    try{ 
     SendMessageResponse sendMessageresponse = SQS.SendMessage(sendMessageRequest); 
    catch(InvalidMessageContents ex){ //Catch or bubble the exception up. 
    //I can't do anything about this so toss the message... 
    LOGGER.log("Invalid data in request: "+data, ex); 
    return null; 
    } catch(Throttling ex){ //I can do something about this! 
    //Exponential backoff... 
    } 
    return sendMessageresponse.MessageId; 
} 

例外像ThrottlingServiceUnavailable是那些經常被忽視,但可以妥善處理。它的commonly recommended對於這樣的事情,你實現了指數退避。當你遏制你退縮時,直到服務再次可用。 Java中的實現和使用示例:https://gist.github.com/alph486/f123ea139e6ea56e696f