如何阻止NServiceBus重试HASN&#T; T抛出异常的消息?

时间:2014-12-08 09:01:12

标签: nservicebus

我遇到了与重试有关的行为,我无法在我尝试的文档或搜索中找到任何参考。本质上,如果我的处理程序处理消息的时间超过60秒(注意它不会抛出异常),NServiceBus将触发另一个处理程序来处理相同的消息。这意味着处理程序完成的工作(至少)运行两次(通常是我将MaxRetries配置为5次的5次)。

我只希望重播消息,如果它确实失败了(即抛出异常),而不仅仅是因为它花了超过一分钟。

这种行为是否符合设计?可以关掉吗?是" 60秒"配置?

在日志中,它看起来就像是正在处理的新消息:

2014-12-09 14:50:38,406 [13] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - ChildContainerBehavior
2014-12-09 14:50:38,422 [13] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - MessageHandlingLoggingBehavior
2014-12-09 14:50:38,430 [13] DEBUG NServiceBus.Unicast.Behaviors.MessageHandlingLoggingBehavior - Received message with ID 031e6070-4397-4e55-8670-a3fc00f49d7c from sender Foo
2014-12-09 14:50:38,440 [13] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - ImpersonateSenderBehavior
...
2014-12-09 14:50:40,313 [13] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - InvokeHandlersBehavior
2014-12-09 14:50:40,319 [13] INFO  MyHandler - Running
...
...
2014-12-09 14:51:38,642 [15] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - ChildContainerBehavior
2014-12-09 14:51:38,667 [15] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - MessageHandlingLoggingBehavior
2014-12-09 14:51:38,678 [15] DEBUG NServiceBus.Unicast.Behaviors.MessageHandlingLoggingBehavior - Received message with ID 031e6070-4397-4e55-8670-a3fc00f49d7c from sender Foo
2014-12-09 14:51:38,686 [15] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - ImpersonateSenderBehavior
...
2014-12-09 14:51:38,831 [15] DEBUG NServiceBus.Pipeline.BehaviorChain`1 - InvokeHandlersBehavior
2014-12-09 14:51:38,837 [15] INFO  MyHandler - Running

3 个答案:

答案 0 :(得分:1)

Mauro走在正确的轨道上,但是日志并没有很好地显示出来。我们将SQL服务器用于消息队列。默认情况下,事务将在60秒后超时,但超时不会立即导致任何错误。只有当消息处理完成时,NServiceBus才会尝试更新/移动已完成的消息,但它不能,因为事务不再有效(然后抛出异常)。

第二个处理程序在60秒后启动的原因是因为并发处理已启用,并且一旦事务超时第一个处理程序,该消息实际上可供另一个线程获取(其锁定直到此时)

所以解决方法是在config中添加这样的东西:

  <system.transactions>
    <defaultSettings timeout="00:10:00" />
  </system.transactions>

(假设您使用MSMQ作为邮件传输,可能会应用不同的超时...)

答案 1 :(得分:1)

我有完全相同的症状,问题是通过DTC(分布式事务)长时间运行的事务。

正如Mauro所说,DTC的默认超时为60秒。 这可以在系统上更改:

启动“组件服务”,然后展开“组件服务 - &gt;计算机 - &gt;我的电脑”,右键单击并选择“属性”。在选项选项卡上,您可以设置所需的默认超时。

或者,您可以使用 app.config

进行更改
<configuration>
  <system.transactions>
    <defaultSettings timeout="00:10:00"/>
  </system.transactions>
</configuration>

但是,这里有一个警告。默认系统超时仍设置为10分钟! 如果您知道交易持续时间超过10分钟,则需要将以下内容添加到 machine.config

<configuration>
  <system.transactions>
    <machineSettings maxTimeout="01:00:00" />
  </system.transactions>
</configuration>

machine.config位于

%windir%\Microsoft.NET\Framework64\[version]\config\machine.config

参考文献:

DTC troubles with long running transactions in NServiceBus

Override the System.Transactions default timeout of 10 minutes in the code

Where is my machine.config?

答案 2 :(得分:0)

对于那些根本不希望NServiceBus搞乱交易内容的人(也就是说我的交易方式,dude),可以简单地让NSB停止在事务范围内管理处理程序:

//e.g. When using the BusConfiguration object:
 config.Transactions()
     .DoNotWrapHandlersExecutionInATransactionScope();