我对NserviceBus很新,我有一个NServiceBus应用程序,它使用一个命令来处理消息,该命令创建包含不同命令的多个子消息。
例如,我将消息BulkOrder01放在队列中,该队列由我的BulkOrder消息处理程序获取。我的BulkOrder01的有效负载包含批量订单ID,当在数据库中查找时,返回4000个订单。对于每个子订单,我都会向订单发送订单消息。
这似乎在我们的生产环境中工作不到1000个子订单,但是一旦我们达到1000以上,我们经常会看到父邮件没有被处理,因此没有创建子邮件。
在本地运行时,我发现它会将一个或两个子消息发送到队列,但随后会出现NServiceBus.Unicast.Queing异常。 FailedToSendMessgeException
' 无法向地址发送消息:Namespace.OrderService@MyComputername '内部异常是' System.Messaging.MessageQueueException 无法登记交易'
我发现如果我在EndpointConfig中设置DoNotWrapHandlersExecutionInATransactionScope
,那么在出现之前我不会得到异常,因为父消息会超时。我可以通过增加事务超时来防止。
然而,设置DoNotWrapHandlersExecutionInATransactionScope
会让我感到紧张,我似乎无法找到有关这实际上的内容的更多信息。显然,不会将处理程序执行包装在事务范围中,但是从我执行的测试开始,它仍然表现为事务性行为,因此如果父消息失败,则不会发送任何子消息。我记得读过有多层交易范围 - 这只是删除其中一个层吗?
也许整个方法的解决方法都是错误的 - 我知道NserviceBus中存在Sagas但是没有真正关于它们的可能我所描述的过程应该使用Saga来完成......
谷歌搜索异常购买它是一个超时问题,但是我发现只增加它的超时只是通过超时量延迟异常。它只在DoNotWrapHandlersExecutionInATransactionScope
设置时才在本地工作。在rpoduction中,它似乎更可靠地工作,并且仅在大量子消息上失败。
创建的子消息似乎需要相当长的时间才能添加到队列中,大约50毫秒,当扩展到4000条消息时总共需要3.3分钟。这似乎很长一段时间将一条小消息放入队列中可能没有正确配置?
我在运行NServiceBus 4.3.0.0的C#4.5环境中使用Entity Framework访问数据库和Unity进行依赖注入
我正在使用IBus.SendLocal
发送消息,我按照以下方式配置超时和设置:
NServiceBus.Configure.Transactions.Advanced(x => x.DefaultTimeout(new TimeSpan(0, 5, 0)));
NServiceBus.Configure.Transactions.Advanced(x => x.DoNotWrapHandlersExecutionInATransactionScope());
任何人都可以指出我正确的方向,如果我正确地做到这一点 - 是预期的慢(ish)性能。感谢。
答案 0 :(得分:1)
我们有一个类似的过程,挑战在于所有这些工作都包含在你发现的同一个交易中。您将需要创建另一个端点来处理子消息。
我建议在NSB中配置分发服务器并让分发服务器将所有子处理委派给工作人员。因此,您可以根据需要扩展子消息的处理。