2014-07-07 42 views
0

我使用Azure队列后端测试NServiceBus。我配置使用NServiceBus所有默认设置,并有这样的代码来发送消息:当使用NServiceBus使用Azure队列时Bus.Send被阻塞

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); 
} 

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

现在我有两个问题:

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

回答

0

数据属性的大小是多少?

我刚刚自己运行了这个测试(使用字符串“Whatever”作为数据),并且我发现每个远程发送的平均延迟为〜50ms,每15秒钟调节一次油门,使得在该点的调用需要约300ms (这是预期的)。

请注意,azure存储是基于远程http的服务,因此可能因距离而延迟,但据我所知,这里没有公布的性能目标。此外,它还具有主动节流功能,以便在数据移动时可以推回,这大约每15秒发生一次(请参阅我的存储内部通信以了解幕后发生了什么)

关于异步/等待。如果你的目的是疏通UI线程,比继续前进,做这样......

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

如果你的目的是实现更高的吞吐量,你应该使用更多的发送线程,而不是作为一个线程需要无论如何要等待http响应,这是发送线程或从异步/等待中触发的后台线程。但请注意,无论您使用多少个发送威胁,每个队列也会被单独限制(以几百个信息/秒)

PS:IT建议在.net服务点管理器上更改以下设置,以优化它对于许多小型的http请求的

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

希望这有助于...

+0

感谢您的答复。问题不在于长时间的延迟。预计从我的开发机器300毫秒。问题是没有async \ await选项,并且在发送消息时必须阻塞线程。我们希望在一台机器上每秒处理1000个请求。如果我们这样做,我们将至少有1000个线程正在旋转并等待来自NServiceBus的响应。当您执行async \ await时,线程将在等待期间释放。否则,线程就处于等待状态并阻塞。 –

+0

这是在团队雷达提供,但现在我建议你使用多个发送线程包装发送并行为例如 –

+0

并使用多个队列以及顺便说一句,你将无法填充成千上万的消息无论您使用多少个线程,都可以始终通过单个队列 –