2014-10-30 128 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