繁体   English   中英

Azure Service Bus-python客户端消息上的AutoRenewTimeout

[英]Azure Service Bus - AutoRenewTimeout on messages for python client

我正在查看服务AutoRenewTimeout功能的文档,并发现了有关服务总线消息上的锁定续订策略的文章

它讨论了AutoRenewTimeout功能,该功能将消息锁定一段时间,以便订阅者可以完成对消息的处理,或者消息超时(无法在给定的时间段内处理消息),在该时间内消息将被锁定。对从同一订阅中读取的其他订阅者可见。

我在Microsoft Azure Python版SDK中找不到此功能。 我遍历了源代码,它只讨论了手动更新特定消息上的锁

我的用例如下

  • 我必须阅读并处理来自servicebus的消息。
  • 将那些已处理的消息转储到数据库中(在我的情况下为MongoDB)
  • 推送到Servicebus的消息每小时可能高达1百万个事件(因此无法跟踪给定消息何时超时并​​为此进行手动更新)。
  • 所有这些已处理的消息都被推送到临时列表。
  • 每当以上列表超过特定阈值时,请在数据库上进行批量插入

这是我想出的。 它与我所说的锁定更新策略无关。 我只是在处理邮件时触发删除操作。

class Event:
    def __read_subscription_message(self):
        try:
            message = self.bus_service.receive_subscription_message(
                self.topic_name, self.subscription_name, peek_lock=True)
            return message
        except Exception as e:
            self.logger.exception("Exception occurred!!!")

    def start_listner(self, task_number=0):
        self.logger.info('Task: %s, started listening to service bus messages' % task_number)
        while True:
            msg = self.__read_subscription_message()
            if msg and msg.body is not None:
                self.currentBackOff = 0
                self.process_event(msg, task_number)
                gevent.sleep(0)

    def process_event(self, msg, task_number=0):
        try:
            if msg.body:
                # message = json.loads(msg.body.decode())
                message = self.deserialize_message_body(msg.body)
                custom_properties = msg.custom_properties
                # Business logic implemented................
                # After processing a message append this to a temp list. Make
                # an insert which length of this list reaches a given threshold
                # by calling "write_to_storage(self, task_number=0)"
                self.bulk_records.append(record)
                msg.delete()
            else:
                self.logger.info("Message received: %s, is of type: %s" % (msg.body, type(msg.body)))
            self.total += 1
        except DeSerializationException as e:
            self.logger.info("Not able to de-serialize message: %s" % msg.body)
            self.logger.exception(e)
        except Exception as e:
            self.logger.exception(e)

    def write_to_storage(self, task_number=0):
        # Write to DB

它工作正常,但是如果我的订户进程被杀死,那么所有在我的临时存储桶中的消息(未写入数据库)都将丢失。 我希望在将消息写入数据库时​​在它们上触发一个手动的“ message.delete() ”。 我认为AutoRenewLockAutoRenewLock的方法,因为一条消息的锁定持续时间的最大值是5分钟,这对我来说没有帮助。

谢谢

因此,您无需将消息写在临时日志中。 如果您使用窥视锁并且该锁已过期,则该消息应返回到队列中,并在下一次接收。 如果使用窥视锁,则需要调用在代码中执行的message.delete(),只有这样,才应将其从代理中删除。 该.net示例显示了其应如何工作: https : //docs.microsoft.com/zh-cn/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues

为了方便起见://完成消息,以免再次收到。 //仅当queueClient是在ReceiveMode.PeekLock模式(默认设置)下创建的,才可以这样做。

等待queueClient.CompleteAsync(message.SystemProperties.LockToken);

另请参阅此处有关应该如何使用窥视锁的信息: https : //docs.microsoft.com/zh-cn/rest/api/servicebus/peek-lock-message-non-destructive-read

因此,除非您调用msg.delete,否则该消息不应视为已完成。 您是否在同一订阅或主题上运行多个订阅者?

无论您什么都不叫删除,消息都应该回到队列中,您的下一个接听电话将接听这些消息。 如果您多次收信失败,他们可能会死信。 https://docs.microsoft.com/zh-cn/azure/service-bus-messaging/service-bus-dead-letter-queues

请使用服务总线资源管理器来查看您是否实际上松散了消息,或者它们只是回到队列中还是发了死信: https : //github.com/paolosalvatori/ServiceBusExplorer/releases

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM