【发布时间】:2012-08-07 17:35:00
【问题描述】:
我在 Python 中使用 boto 库来获取 Amazon SQS 消息。在特殊情况下,我不会从队列中删除消息,以便进行更多更改以恢复临时故障。但我不想不断收到失败的消息。我想要做的是在收到超过 3 次后删除消息,或者如果接收计数超过 3 则不收到消息。
最优雅的做法是什么?
【问题讨论】:
标签: python boto amazon-sqs
我在 Python 中使用 boto 库来获取 Amazon SQS 消息。在特殊情况下,我不会从队列中删除消息,以便进行更多更改以恢复临时故障。但我不想不断收到失败的消息。我想要做的是在收到超过 3 次后删除消息,或者如果接收计数超过 3 则不收到消息。
最优雅的做法是什么?
【问题讨论】:
标签: python boto amazon-sqs
至少有几种方法可以做到这一点。
当您在 boto 中阅读消息时,您会收到一个 Message 对象或其某个子类。 Message 对象有一个“attributes”字段,它是一个包含 SQS 已知的所有消息属性的 dict。 SQS 跟踪的一件事是消息被读取的大致次数。因此,您可以使用此值来确定是否应删除消息,但您必须对值的“近似”性质感到满意。
或者,您可以在某种数据库中记录消息 ID,并在每次阅读消息时增加数据库中的计数字段。如果消息总是在单个进程中被读取,这可以在一个简单的 Python dict 中完成,或者如果您需要跨进程记录读数,它可以在 SimpleDB 之类的东西中完成。
希望对您有所帮助。
下面是一些示例代码:
>>> import boto.sqs
>>> c = boto.sqs.connect_to_region()
>>> q = c.lookup('myqueue')
>>> messages = c.receive_message(q, num_messages=1, attributes='All')
>>> messages[0].attributes
{u'ApproximateFirstReceiveTimestamp': u'1365474374620',
u'ApproximateReceiveCount': u'2',
u'SenderId': u'419278470775',
u'SentTimestamp': u'1365474360357'}
>>>
【讨论】:
您可以在 SQS 队列中的消息末尾添加一个额外的标识符。这个标识符可以保持消息被阅读的次数的计数。
此外,如果您希望您的服务不应该一次又一次地轮询这些消息,那么您可以再创建一个队列,例如“死消息队列”,然后可以将超过阈值的消息传输到该队列。
【讨论】:
aws 对此具有内置支持,只需按照以下步骤操作:
它的工作原理是,每当工作人员收到消息时,接收计数就会增加。一旦达到“最大接收”计数,消息就会被推送到死信队列。请注意,即使您通过 aws 控制台访问消息,接收计数也会增加。
【讨论】:
从您阅读的消息中获取 ApproximateReceiveCount 属性。 将其移动到另一个队列(而不是您可以管理错误消息)或将其删除。
foreach (var message in response.Messages){
try{
var notifyMessage = JsonConvert.DeserializeObject<NotificationMessage>(message.Body);
Global.Sqs.DeleteMessageFromQ(message.ReceiptHandle);
}
catch (Exception ex){
var receiveMessageCount = int.Parse(message.Attributes["ApproximateReceiveCount"]);
if (receiveMessageCount >3 )
Global.Sqs.DeleteMessageFromQ(message.ReceiptHandle);
}
}
【讨论】:
应该分几步完成。
应该像魅力一样工作。
【讨论】: