如果我向主题发送一批消息,并使用Subscription客户端读取消息,那么我似乎按顺序接收消息,即对每个发送的消息触发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毫秒,因此我不希望消息在此之前返回(事实上在此之后不久收到第一条消息),但是我不希望累积的&#39;我看到的行为。
使用MaxConcurrentCalls并在OnMessageAsync中添加延迟,显示它按预期工作,我只能看到一次处理MaxConcurrentCalls
我已经搞乱 DeleteOnReceive 模式,启用&#39; 快递&#39;,禁用&#39; 分区&#39;,使用 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已发送消息918: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收到消息8在1347 millis
18:09:34.065收到1492毫克的消息9
答案 0 :(得分:0)
基本上,您处理的消息很多比服务总线可以提供更快的消息。 Azure SB在个人消息的基础上相对较慢。通过在完成之前添加Task.Delay
来验证这一点,并记录线程ID,您应该看到多个副本旋转。
答案 1 :(得分:0)
在深入了解 OnMessage 消息泵的运行方式后,我意识到这实际上是一个轮询机制,其中对ServiceBus的底层调用仍然是& #39;接收()&#39;尝试拉任何新邮件。如果超时,则无限次地再次呼叫。 如果对Receive()的调用仅返回单个消息,然后需要a150ms往返来检索下一个等等,我看到的行为才有意义。
输入 PrefetchCount 。在SubscriptionClient上将此值设置为非零值有效地允许底层Receive()下拉多条消息,然后缓存这些消息并使其(立即)可用于冒泡进入OnMessage。