2014-01-09 102 views
2

我正在使用天蓝色的队列存储来发送电子邮件。电子邮件存储在队列存储中,并且队列一次发送20封电子邮件。Azure队列存储不发送队列消息

//Checks for messages inn the queue 
foreach (CloudQueueMessage msgin sendEmailQueue.GetMessages(20, TimeSpan.FromSeconds(50))) 
    { 
     ProcessQueueMessage(msg); 

    } 

我遇到的问题是,当电子邮件被添加到队列使用不正确的SMTP细节(如密码错误),消息队列中停留,因为它无法发送,并防止在队列中的其他消息从发送。

private void ProcessQueueMessage(CloudQueueMessage msg) 
{ 
    try 
    { 
    //We try to send an email 
    SendEmail(emailRowInMessageTable, htmlMessageBodyRef, textMessageBodyRef); 

    } catch (SmtpException e) 
    { 
    string err = e.Message; 

    //When an error occurs we check to see if the message failed to send certain no. of  
     times 
    if (msg.DequeueCount > 10) 
    { 
     //We delete the message from queue 
     sendEmailQueue.DeleteMessage(msg); 

     return; 
    } else 
    { 
     //delete from top of queue 
     sendEmailQueue.DeleteMessage(msg); 

     //insert into end of queue 
     sendEmailQueue.AddMessage(msg); 

     return; 
    } 
    } 
} 

我尝试的解决方案是从队列中删除的消息,如果有一个错误,并将其添加 回导致正确的电子邮件被发送队列的末尾。但是,删除和添加 消息回到队列重置其离队的性能,因为我使用的离队属性,以确保消息是不是在队列永远是不理想 。

将最好的解决办法是在这种情况下怎么办?

回答

1

您并不需要删除该消息并添加它。一旦消息的visibility timeout时间段(您的情况为50秒)已过期,它将自动返回到队列中。这样,你的DequeueCount逻辑也可以工作,因为同样的消息被取出并再次入队。

请注意,Windows Azure的队列是尽力而为FIFO ...所以它并不总是必要的,消息将被加入他们的时间的基础上回升。你可以做几件事情:

  • 减少重试次数(目前有10个,你可以将其降低到5)或
  • 检查实际的异常。如果由于凭据不正确而导致进程失败,那么在下次和下一次之后该进程将失败。重试该消息没有意义。您可以将该消息移至毒性队列中,以便稍后检查该消息。
+0

从我的理解,如果前30个消息是阻塞队列(即错误的密码),接下来的20正确的消息不会被作为第一个30条消息始终在队列中。这就是为什么我想删除前30条消息并将其添加到队列末尾,以便可以发送20条正确的消息。 – Kaladin

+0

更新了我的答案。 HTH。 –

+0

我们已经检查了不正确的邮件,如不正确的电子邮件ID等,并将其移至毒性队列。不正确的密码只是一个例子,我更多地考虑SMTP服务器何时关闭等等。我将更详细地解释我们的解决方案。 我们有几个SMTP服务器,我们决定使用两个队列来处理消息。 第一次将尝试消息5次,如果失败,则将其移动到第二个队列。第一个队列将每分钟尝试一次消息,第二个队列每隔60分钟尝试一次消息。 – Kaladin