Azure服务总线是否可能创建了该消息的副本?

Azure服务总线是否可能创建了该消息的副本?,azure,azureservicebus,Azure,Azureservicebus,我们在Azure服务总线中遇到了一些奇怪的行为,除了Azure中的一些错误之外,我们无法理解如何解释这些行为。事情是这样的: 我们曾经向Azure服务总线发送过一条消息 发送消息的调用花费了一分钟多一点的时间来执行,但还是成功了,消息在这之后被很好地接收到 大约半秒后,EnqueuedTimeUtc和SequenceNumber出现了一条重复消息,该消息与第一条消息不同,但其内容和我们生成的MessageId相同 现在我们可以相当肯定的是,我们只调用了一次SendMessage,因为在此之前我们

我们在Azure服务总线中遇到了一些奇怪的行为,除了Azure中的一些错误之外,我们无法理解如何解释这些行为。事情是这样的:

  • 我们曾经向Azure服务总线发送过一条消息
  • 发送消息的调用花费了一分钟多一点的时间来执行,但还是成功了,消息在这之后被很好地接收到
  • 大约半秒后,
    EnqueuedTimeUtc
    SequenceNumber
    出现了一条重复消息,该消息与第一条消息不同,但其内容和我们生成的
    MessageId
    相同
  • 现在我们可以相当肯定的是,我们只调用了一次
    SendMessage
    ,因为在此之前我们确实记录了日志,并且我们也记录了所有接收到的消息

    我们也不认为这是客户端库做的,因为在总线上出现的这两条消息之间发送了其他消息,我不认为客户端库在后台做这件事,同时允许其他人通过。但这一点并非100%确定。以下是我们发现的情况:

  • 发送第一条消息
  • 完成操作需要约63秒
  • 之后会发送一些其他消息
  • 在发送第一条消息大约30秒后,会出现一个副本(至少根据EnqueuedTime)

  • 所以问题是:是否有人经历过类似的事情,这可能是Azure本身的bug/暂时性问题,他们是否有任何保证不会发生这种情况?由于通话持续了一分钟以上,我怀疑当时Azure中有什么东西可能导致了这一情况(例如更新或类似的事情)

    这可能会发生,这是一种“正常”现象。Service Bus SDK具有内部自动重试策略以克服暂时性错误。因此,如果第一次尝试成功,但由于网络问题导致响应丢失,它将再次尝试并有效地传递两次消息

    客户机或网络级别的错误可能会提前一刻发生,发送的消息可能会提交到队列中,而确认不会成功返回到客户机。这种情况会让客户端对发送操作的结果产生疑问

    要解决此问题,可以每隔一段时间启用。这将防止在此间隔内发送重复的消息ID

    有一个缺点:

    请注意,启用重复检测和窗口大小直接影响队列(和主题)吞吐量,因为所有记录的消息ID必须与新提交的消息标识符匹配


    理想情况下,你会有幂等接收器,这意味着它准备好了重复。但这并不总是可能/方便的。

    我认为您的消息发送应用程序在向服务总线消息实体发送消息时遇到了一些错误或延迟。因此,它尝试发送具有相同消息Id但序列号不同的相同消息

    Azure Service Bus为我们提供了重复检测属性,以防止在队列中接收重复的消息副本,即具有相同消息ID的消息。通过将重复检测时间历史设置为预定义的时间间隔来启用队列的“重复检测”属性时,队列中只有一条具有相同消息Id的消息可用,并且具有重复消息Id的消息将丢失


    您可以通过使用重复检测属性来避免问题,还可以向服务总线队列或主题发送带有自定义消息Id的消息。

    是的,我希望使用幂等接收器,但不幸的是,这是不可能的,因为我们对Firebase使用的API根本不是任何幂等的。您的意思是说可能有客户端库尝试发送了两次?我们已经想到了这一点,但情况可能并非如此,因为在这两者之间发送了其他消息。我已经用更多的细节扩展了这个问题。@IlyaChernomordik同一个客户端可以从不同的线程并行发送多条消息,具体取决于您的消息通道工厂配置。稍后的一个启动程序可以提前完成。我们只有一个发送消息的线程。我的意思是,在同一线程的后台重试时,
    SendMessage
    不会成功?这也是我们所想的,因此它看起来不会因为客户端库本身而成功,而是因为服务器端的Azure。当然,很难100%检测到,这就像几十万条消息中的一条。服务总线是一个分布式系统,所以我认为同样的原则适用于任何情况。如果您需要担保,请使用提供担保的功能,否则请准备好应对异常。嘿,谢谢您的回答。是的,我们知道重复检测,但在发生这种情况时它没有打开。至于延迟和重发,所以我非常怀疑,因为在消息的第一次和第二次出现之间发送了具有相同ID的其他消息,尽管我当然不确定客户端库是如何做到这一点的。我并不完全相信客户端重试机制复制您的消息的假设。1) 您可以共享一个复制代码(GitHub或类似的)吗?2) 您是否向客户团队提出了验证此方案的问题?@SeanFeldman我不完全确定您的意思,因为我实际上怀疑这是客户库(或者您的意思是库?)。不幸的是,我无法重现这个问题,因为它在几十万条消息中只发生过一次,而代码实际上只是消息列表上带有.Send()的循环。我不确定你能从中提取出什么有用的东西,但我可以试着找出一个精练的例子。至于