我遇到了与重试有关的行为,我无法在我尝试的文档或搜索中找到任何参考。本质上,如果我的处理程序处理消息的时间超过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
答案 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
答案 2 :(得分:0)
对于那些根本不希望NServiceBus搞乱交易内容的人(也就是说我的交易方式,dude),可以简单地让NSB停止在事务范围内管理处理程序:
//e.g. When using the BusConfiguration object:
config.Transactions()
.DoNotWrapHandlersExecutionInATransactionScope();