【问题标题】:How do I stop NServiceBus retrying a message that HASN'T thrown an exception?如何停止 NServiceBus 重试未引发异常的消息?
【发布时间】:2015-07-23 06:23:39
【问题描述】:

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

【问题讨论】:

  • 看看端点日志,有可能发生的事情是事务超时(默认超时为 1 分钟)并基本上抛出异常并重试消息.
  • 我在日志中看到的(我在上面添加的)只是运行所有行为的管道行为链,就好像收到了一条新消息一样。与事务超时无关。

标签: nservicebus


【解决方案1】:

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

第二个处理程序仅在 60 秒后启动的原因是因为启用了并发处理,并且一旦第一个处理程序的事务超时,该消息有效地可供另一个线程获取(直到此时它被锁定) .

所以解决方案是在配置中添加这样的东西:

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

(大概如果您使用 MSMQ 作为消息传输,可能会应用不同的超时...)

【讨论】:

  • 哇!你比我早一小时得到了自己的答案! (:但是请看一下我对机器配置的评论,这样您就不会意外地再次陷入(几乎)相同的陷阱!
【解决方案2】:

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

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

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

或者,您可以使用 app.config 进行更改:

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

但是,这里有一个警告。默认的 system 超时仍然设置为 10 分钟! 如果您知道您的交易将持续超过 10 分钟,则需要将以下内容添加到您的 ma​​chine.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?

【讨论】:

  • 如果有人知道如何让 NServiceBus 隐藏此错误,请发表评论。根本有问题的事实一开始并不是很明显。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多