Azure Service Bus是否可以创建消息的副本?

时间:2018-08-14 07:49:46

标签: azure azureservicebus

我们在Azure Service Bus中遇到了一些奇怪的行为,除了Azure中的一些错误之外,我们无法弄清楚如何解释。这就是发生的事情:

  1. 我们曾经一次向Azure Service Bus发送消息
  2. 发送消息的调用花费了超过一分钟的时间才能执行,但仍然成功,并且此后收到了很好的消息
  3. 出现了一条重复的消息,EnqueuedTimeUtc大约半秒后出现,SequenceNumber与第一条消息不同,但是内容和我们生成的MessageId相同

现在,我们可以肯定的是,我们仅对SendMessage进行过一次呼叫,因为我们确实在此之前进行了日志记录,并且也记录了所有收到的消息。

我们也不认为这是由客户端库执行的,因为在总线上出现的这两个消息之间还有其他消息发送,我不认为客户端库会在后台执行此操作而允许其他人执行经过。虽然不是100%确定。这是我们发现发生的事情:

  1. 第一个消息已发送
  2. 完成该操作大约需要63秒
  3. 之后还会发送其他一些消息
  4. 在发送第一条消息大约30秒后,出现重复(至少根据EnqueuedTime)。

所以问题是:有人经历过类似的事情吗?Azure本身是否可能是错误/暂时性问题,他们是否有保证不会发生这种情况?由于通话耗时超过一分钟,我怀疑当时Azure可能正在发生某些事情(例如更新等)

2 个答案:

答案 0 :(得分:2)

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

  

客户端或网络级别的错误可能会更早发生,并且发送的消息可能会提交到队列中,而确认未成功返回给客户端。这种情况使客户端对发送操作的结果产生疑问。

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

有一个缺点:

  

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

理想情况下,您将拥有幂等接收器,这意味着它已准备好进行重复。但这并不总是可能/方便的。

答案 1 :(得分:1)

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

Azure服务总线利用重复检测属性来防止接收队列中消息的重复副本,即具有相同消息ID的消息。通过设置具有预定时间间隔的重复检测时间历史记录来启用队列的重复检测属性时,队列中只有一条具有相同消息ID的消息将可用,并且具有重复消息ID的消息将丢失。

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