使用Azure Queue和NServiceBus时Bus.Send阻塞

时间:2014-07-07 05:57:35

标签: nservicebus azure-queues

我正在使用Azure Queue后端测试NServiceBus。我使用所有默认设置配置了NServiceBus,并使用此代码发送消息:

while ((data = Console.ReadLine()) != null)
{
   Stopwatch sw = new Stopwatch();
   sw.Start();
   Bus.Send("testqueue", new Message() {Data = data});
   sw.Stop();
   Console.WriteLine("Sent time: " + sw.ElapsedMilliseconds);
}

在我的开发机器上运行时,向队列发送消息大约需要700毫秒。当使用Azure存储客户端直接编写时,队列很远,大约350ms。

现在我有两个问题:

  1. 我不希望线程在Bus.Send调用上阻塞。一种选择是使用async \ await模式。另一种选择是使用内存队列来传递消息,类似于0MQ。最后一个选项并不保证当然的交付,但假设有一些监控功能,我可以忍受。
  2. 为什么发送消息需要两倍的时间来简单写入队列?这可以优化吗?

1 个答案:

答案 0 :(得分:0)

数据属性的大小是多少?

我自己运行了这个测试(使用字符串“Whatever”作为数据),我发现每个远程发送的平均延迟为~50ms,每15秒有一个限制,使得此时调用大约需要300ms(这是预期的。)

请注意,azure存储是基于远程http的服务,因此会因距离而受到延迟的影响,据我所知,此处没有公布的性能目标。此外,它还具有主动限制功能,可以在数据移动时向后推动,大约每15秒发生一次(请参阅我的存储内部通话,以了解幕后发生的事情。http://www.slideshare.net/YvesGoeleven/azure-storage-deep-dive

关于async / await的主题。如果您的目的是取消阻止UI线程,那么继续这样做......

await Task.Factory.StartNew(() => _bus.Send(new Message{
       Whatever = data
})).ConfigureAwait(false);

如果您的目的是实现更高的吞吐量,则应该使用更多的发送线程,因为线程需要等待http响应,无论是发送线程还是从async / await触发的后台线程。但是请注意,无论您使用多少发送威胁,每个队列也会被单独限制(几百msgs /秒)

PS:我们还建议在.net服务点管理器上更改以下设置,以针对许多小型http请求进行优化

ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 48;

希望这会有所帮助......