【问题标题】:Azure Service Bus SubscriptionClient high latency / not receiving messages concurrentlyAzure Service Bus SubscriptionClient 高延迟/不同时接收消息
【发布时间】:2018-03-18 11:41:55
【问题描述】:

如果我向一个主题发送一批消息,并使用订阅客户端读取消息,那么我似乎按顺序接收消息,即每发送一条消息都会触发 OnMessageAsync,但是有一个每个接收事件之间有明显的(150+ 毫秒)延迟

发件人

var factory = MessagingFactory.CreateFromConnectionString("blah");
sender = factory.CreateMessageSender("MyTopicName");

var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
    tasks.Add(sender.SendAsync(new BrokeredMessage("My Message"))
       .ContinueWith(t => Log("Sent Message {i}"));

await Task.WhenAll(tasks);  // This completes within a few millis

接收者

receiver = factory.CreateSubscriptionClient("MyTopicName", "MySubscription");
_sbClient.OnMessageAsync(async message =>
{
    var msg = message.GetBody<string>();
    Log("Received message xxxx
    await message.CompleteAsync();
});

这意味着发送的第 10 条消息仅在发送后 1.5 秒多后才收到。

Azure 延迟测试显示我正在使用的数据中心有大约 200 毫秒的延迟,因此我不希望在此之前返回消息(实际上在此之后不久就会收到第一条消息),但我不会期待我看到的“累积”行为。

玩转 MaxConcurrentCalls 并在 OnMessageAsync 中添加延迟,表明它按预期工作,我只能看到一次只处理 MaxConcurrentCalls

我搞砸了 DeleteOnReceive 模式,启用“Express”,禁用“Partitioning”,使用 AMQP 而不是 SBMP 等,但似乎没有什么太大的区别。

[我正在使用 Microsoft.ServiceBus,版本=3.0.0.0]

编辑:
这是日志的样子。因此,如果我同时发送 10 条消息,我只会在发送 1.5 秒后收到第 10 条消息:

18:09:32.624 发送消息 0
18:09:32.624 已发送消息 1
18:09:32.641 发送消息 2
18:09:32.641 发送消息 3
18:09:32.674 发送消息 4
18:09:32.674 发送消息 5
18:09:32.709 已发送消息 6
18:09:32.709 已发送消息 7
18:09:32.738 发送消息 8
18:09:32.738 发送消息 9

18:09:32.791 在 341 毫秒内收到消息 1
18:09:32.950 在 487 毫秒内收到消息 2
18:09:33.108 在 628 毫秒内收到消息 3
18:09:33.265 在 770 毫秒内收到消息 4
18:09:33.426 在 914 毫秒内收到消息 5
18:09:33.586 在 1060 毫秒内收到消息 6
18:09:33.745 在 1202 毫秒内收到消息 7
18:09:33.906 在 1347 毫秒内收到消息 8
18:09:34.065 在 1492 毫秒内收到消息 9

【问题讨论】:

    标签: c# azure servicebus


    【解决方案1】:

    在深入了解 OnMessage 消息泵的工作原理后,我意识到这实际上是一个 轮询 机制,其中对 ServiceBus 的底层调用仍然是一个 ' Receive()' 尝试任何新消息。如果超时,则无限次再次调用。 如果对 Receive() 的调用只返回一条消息,然后需要 150 毫秒的往返时间来检索下一条等,那么我看到的行为是有意义的。

    输入 PrefetchCount。在 SubscriptionClient 上将此设置为非零值有效地允许底层 Receive() 下拉多条消息,然后将其缓存并(立即)可用于冒泡到 OnMessage 中。

    【讨论】:

      【解决方案2】:

      基本上,您处理消息的速度比服务总线传递新消息的速度快得多。 Azure SB 在单个消息的基础上相对较慢。通过在完成前添加 Task.Delay 并记录线程 ID 来验证这一点,您应该会看到多个副本启动。

      【讨论】:

      • 如果我同时发送消息,我希望以相似的并发级别接收它们。我不敢相信 ASB 的性能这么差...一定是配置/我的实现!
      • 我发现服务总线的交付性能可能会有很大差异,但它从来都不是特别快(有时只是“慢得多”)。多年来,许多其他人也得出了同样的结论。一些例子herehere
      猜你喜欢
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2022-08-17
      • 1970-01-01
      • 2022-10-08
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      相关资源
      最近更新 更多