最近我们注意到我们的Nservicebus用户无法处理不断增加的负载。我们有一个相当恒定的事件输入流(来自嵌入式设备的测量数据),因此吞吐量跟随输入非常重要。
经过一些分析后,我们得出结论,这不是处理花费大量时间的事件,而是NServiceBus检索和发布事件的过程。为了更好地了解发生了什么,我重新创建了Pub / Sub示例(http://particular.net/articles/nservicebus-step-by-step-publish-subscribe-communication-code-first)。
在我的笔记本电脑上,使用所有NServiceBus默认值,Ordering.Server的最大吞吐量约为10个事件/秒。它唯一能做的就是
class PlaceOrderHandler : IHandleMessages<PlaceOrder>
{
public IBus Bus { get; set; }
public void Handle(PlaceOrder message)
{
Bus.Publish<OrderPlaced>
(e => { e.Id = message.Id; e.Product = message.Product; });
}
}
然后我开始玩配置设置。似乎没有人对这个(非常低的)性能产生任何影响:
Configure.With()
.DefaultBuilder()
.UseTransport<Msmq>()
.MsmqSubscriptionStorage();
使用此配置,吞吐量立即达到60条消息/秒。
我有两个问题:
使用MSMQ作为订阅存储时,性能远优于RavenDB。为什么像订阅数据存储这样微不足道的事情会产生这样的影响呢?
我本来期望更高的性能。是否有任何其他配置设置我应该使用至少比这更好的一个数量级?在我们的服务器上,运行此样本时的最大吞吐量约为200 msg / s。对于一个甚至没有做任何有用的系统来说,这远非壮观。
答案 0 :(得分:1)
MSMQ没有原生的pub / sub功能,因此NServiceBus通过存储订阅者列表然后循环遍历该列表向每个订阅者发送事件副本来增加对此的支持。这转换为X消息队列操作,其中X是订户的数量。这解释了为什么RabbitMQ更快,因为它具有本机pub / sub,因此您只需要对代理进行一次操作。
基于msmq队列的存储速度更快的原因是它是本地存储(如果需要扩展端点则无法使用),这意味着我们可以缓存数据不能更新存储的任何其他端点实例。简而言之,这意味着我们可以通过内存查找来实现,您可以看到它是最快的选项。
计划在所有存储中添加本机缓存:
https://github.com/Particular/NServiceBus/issues/1320
200 msg / s听起来很低,如果你跳过公共汽车你会得到多少。发布? (只是为了获得基线)
答案 1 :(得分:0)
可能性1:分布式交易 由于Queue-Database的组合,在处理消息时会创建分布式事务。 尝试在没有事务处理消息的情况下进行测量。这比较如何?
可能性2:msmq可能不是满足您需求的最佳排队系统 有没有考虑过转换到rabbitmq运输?我与RabbitMq结合MassTransit有很好的经验。方式超出了你在问题中提到的数字。