【问题标题】:How to get messages receive count in Amazon SQS using boto library in Python?如何使用 Python 中的 boto 库在 Amazon SQS 中获取消息接收计数?
【发布时间】:2012-08-07 17:35:00
【问题描述】:

我在 Python 中使用 boto 库来获取 Amazon SQS 消息。在特殊情况下,我不会从队列中删除消息,以便进行更多更改以恢复临时故障。但我不想不断收到失败的消息。我想要做的是在收到超过 3 次后删除消息,或者如果接收计数超过 3 则不收到消息。

最优雅的做法是什么?

【问题讨论】:

    标签: python boto amazon-sqs


    【解决方案1】:

    至少有几种方法可以做到这一点。

    当您在 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'}
    >>>
    

    【讨论】:

    • 感谢您的回复。我浏览了 boto 文档,但找不到任何获取消息接收计数的线索。你知道它在哪里吗?顺便说一句,拥有一个简单的本地数据库是我管理此问题的另一种方法,但首先我想保持简单——比如获得接收计数——如果可能的话..
    • 你能添加一个语法示例吗?当我不止一次阅读一条消息并查看 message_instance.attributes 时,我发现的只是一本空字典。
    【解决方案2】:

    您可以在 SQS 队列中的消息末尾添加一个额外的标识符。这个标识符可以保持消息被阅读的次数的计数。

    此外,如果您希望您的服务不应该一次又一次地轮询这些消息,那么您可以再创建一个队列,例如“死消息队列”,然后可以将超过阈值的消息传输到该队列。

    【讨论】:

      【解决方案3】:

      aws 对此具有内置支持,只需按照以下步骤操作:

      1. 创建死信队列
      2. 通过选中“使用重新驱动策略”为源队列启用重新驱动策略
      3. 选择您在步骤#1 中为“死信队列”创建的死信队列
      4. 将“最大接收数”设置为“3”或 1 到 1000 之间的任何值

      它的工作原理是,每当工作人员收到消息时,接收计数就会增加。一旦达到“最大接收”计数,消息就会被推送到死信队列。请注意,即使您通过 aws 控制台访问消息,接收计数也会增加。

      来源Using Amazon SQS Dead Letter Queues

      【讨论】:

        【解决方案4】:

        从您阅读的消息中获取 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);
                    }
                }
        

        【讨论】:

          【解决方案5】:

          应该分几步完成。

          1. 创建 SQS 连接:- sqsconnrec = SQSConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
          2. 创建队列对象:- request_q = sqsconnrec.create_queue("queue_Name")
          3. 加载队列消息:- 消息= request_q.get_messages()
          4. 现在您获得消息对象数组并查找消息总数:- 只做 len(messages)

          应该像魅力一样工作。

          【讨论】:

          • 感谢您的关注,但恐怕这不是我的情况。我不需要 len(messages) 我需要某条消息的接收计数。
          • 是的,boto 中没有定义函数来获取接收计数。我建议您维护一个本地元组,其中包含消息 ID、计数和消息正文。您在一定时间后从队列中加载消息,检查 id 是否存在于元组中,如果是,则增加接收计数,如果接收计数>3,则可以删除该消息。我看到了消息对象的目录,它没有接收计数功能。希望对您的问题有所帮助。
          • 这是我想现在我只有这个选项的替代解决方案。非常感谢..
          • 一些cmets:#1。一个元组将是一个可怕的跟踪这个,使用 collection.Counter 这是一个专门为这个问题设计的字典。 #2。维护任何类型的本地计数意味着您不能以分布式方式操作,而这正是 SQS 促进的行为。 #3。在许多情况下,队列可能太大而无法加载所有消息,而且您当然不希望单个工作人员接收所有消息。
          猜你喜欢
          • 2012-04-28
          • 1970-01-01
          • 1970-01-01
          • 2013-02-03
          • 1970-01-01
          • 1970-01-01
          • 2014-10-15
          • 2018-09-13
          • 2014-10-10
          相关资源
          最近更新 更多