在压力测试期间,NServiceBus Timeoutsdispatcher队列充满了消息

时间:2016-04-25 15:59:53

标签: nservicebus nservicebus5 nservicebus-sagas

我正在对使用2次超时的传奇进行一些压力测试。在测试期间,创造了大约21K的传奇故事。所以这意味着42K的超时,但我注意到saga的timeoutsdispatcher队列被数以百计的消息淹没,直到它崩溃,因为MSMQ存储限制被命中。

因为我将持久性机制从RavenDB切换到SQL Server,所以我看到了这种行为。

有没有人知道可能出现什么问题?

运输:MSMQ
持久性:NHibernate 使用的包裹:

NHibernate version 4.0.4.4000  
NServiceBus version 5.2.14  
NServiceBus.Host version 6.0.0  
NServiceBus.Log4Net version 1.0.0  
NServiceBus.NHibernate version 6.2.7  

测试设置:
*端点1向端点2发送22000条消息 *端点2托管由该消息启动的传奇 *每个传奇发布一个事件然后请求2个超时:1分钟4分钟,1分钟10分钟。

观察到的行为:
*端点1在一分钟内发送22K消息 *端点2(传奇)每秒处理5到10条消息 * 4分钟后,第一次超时被触发,而端点2仍在处理来自队列的消息,因此仍在创建新的传奇实例。
*从那一刻开始,saga端点的timeoutsdispatcher队列充满了消息 *大约10分钟后,timeoutsdispatcher队列已经包含超过170K的消息,并且仍在填满 *一直持续到端点2崩溃,因为命中了MSMQ存储限制,或者处理了来自输入队列的所有消息。如果后者首先出现,则timeoutsdispatcher队列消息计数开始减少,直到最终达到0。

1 个答案:

答案 0 :(得分:3)

您是否使用RavenDB执行相同的压力测试? SQL Server是否在具有快速驱动器的功能上或多或少同等强大?

<强>更新

对你的传奇进行一些检查

  • 是否使用了[Unique]属性并且使用得当?换句话说,您是否为每个传入消息使用唯一ID?这样每个产生2次超时的传入消息都会创建一个独特的传奇实例?如果每个传入的消息都访问相同的Saga,这将极大地限制吞吐量。想象一下,Saga实例已经创建过一次,否则解释将变得复杂。所以Message1进来,试图找到数据库中的行,找到并锁定它。第二条消息同时进入,找到该行但它已被锁定。它将重试。消息3直到Message100进来(如果并发设置为100)并且所有尝试做同样的事情,立即失败。您可以看到这将限制吞吐量一段时间:)
  • 您的Saga表和超时表上是否有正确的索引?
  • 您的最大并发级别设置为什么?

根据消息的数量,您说您发送22k消息,导致44k超时消息。图像所有这些超时都在MSMQ中。想象一下,消息真的非常小,就像1Kb一样。 NServiceBus添加的标头信息可能需要2Kb。这是44.000倍3Kb大约是135兆字节。因此,没有办法可以填充默认配置为1GB的默认MSMQ安装。

这可能意味着您的死信队列完全填满。 Find more information on MSMQ connectionstrings并设置适当的连接字符串。例如

<connectionStrings>
  <add name="NServiceBus/Transport"
    connectionString="deadLetter=false;journal=false;"/>
</connectionStrings>

设置了TimeToBeReceived属性(link)的邮件最终会出现在死信队列中。清除队列也会使所有消息进入死信队列。除非你设置了正确的连接字符串。