我有一个 NServiceBus 配置,该配置在开发人员计算机和我的开发环境中运行良好。
但是,当我将其移至测试环境时,我的消息就开始被丢弃。
这是系统:
- 应用从大型机系统获取 TCP 消息并将其发送到 MSMQ(将其称为
FromMainframe
)。 - 托管在 IIS 中的应用程序具有该 MSMQ 的“Handle”方法并处理来自大型机的消息。
在我的测试环境中,第二步只发生了一半。该消息从 MSMQ 中弹出,但不由我的应用程序处理。
实际上我的数据丢失! NServiceBus 将它们从队列中删除,但我永远无法处理它们。它们甚至不在错误队列中!
这些是我尝试过的事情,试图弄清楚发生了什么:
- 检查配置文件
- 将远程调试器附加到进程以查看
Handle
方法正在做什么Handle
方法永远不会被调用(但是当我附加到开发环境时,我的Handle
方法中的断点被命中,并且一切都完美地工作)。
- 将我的开发版本重新部署到测试环境,然后再次尝试第 2 步(以防版本不完全相同。)
- 再次检查配置文件
- 检查错误队列是否未填满
- 错误队列保持为空(我希望它能填满,这样我的数据就不会丢失)。
- 检查是否有任何其他进程可能从我的 MSMQ 中提取内容
- 我关闭了 IIS 网站,并且
FromMainframe
队列中的消息开始备份。 - 当我重新打开它时,消息消失得相当快(但仍然不是一下子全部消失)。它们消失的速度太快了,我的
Handle
方法无法处理它们。
- 我关闭了 IIS 网站,并且
- 再次检查配置文件。
- 运行 NServiceBusTools\MsmqUtils\Runner.exe\i
- 我运行了它,重新启动,一次又一次地运行它,以获得良好的效果!
- 再次检查配置(我一定是错过了什么,对吧?)
- 检查开发环境配置是否指向测试环境
- 我认为不可能使用另一台计算机的 MSMQ 作为输入队列,但检查一下也没什么坏处。
- 查找任何可能悄悄终止我的消息的 catch block 。
- 最后一次检查配置文件。
- 在另一台计算机上重新创建我的测试环境(运行完美)
- 在 IIS 之外运行我的东西。
- 当我在 IIS 外部托管时(使用 NServiceBus.Host.exe),一切正常。那么它一定是 IIS 的事情,对吗?
- 疯狂并希望堆栈溢出能够提供任何类型的见解。
最佳答案
所以我对发生的事情有足够的了解,可以抛出“答案”。
当我设置 NServiceBus 自托管时,我进行了一个加载消息处理程序的调用。
NServiceBus.Configure.With().LoadMessageHandlers()
(还有更多配置,但为了简洁我省略了它们)
当您调用此函数时,NServiceBus 会扫描组件以查找实现 IHandleMessages<T>
的类。 .
因此,不知何故,在我的测试环境计算机上,ServiceBus 对调用 IHandleMessages 的类的目录进行扫描未能找到我的类(即使程序集绝对存在)。
事实证明,如果 NServiceBus 找不到处理消息的东西,它就会将其丢弃!!!
在我看来,这完全是一个设计错误。 NServiceBus 的整体理念是不丢失数据,但在本例中它就是这样做的!
现在,一旦您了解了这个陷阱,就有几种方法可以解决它。
明确说明您的处理程序应该是什么:
NServiceBus.Configure.With().LoadMessageHandlers<First<MyMessageType>>()
进一步的保护是添加另一个处理程序来处理“其他所有事情”。
IMessage
是所有消息有效负载的基础,因此如果您在其上放置处理程序,它将拾取所有内容。
如果将 IMessage 设置为 handle after您的消息得到处理,然后它将处理 NServiceBus 找不到处理程序的所有内容。如果你在Handle
中抛出异常方法将导致 NServiceBus 将消息移动到error
队列。 (我认为应该是默认行为。)
关于iis - 导致 NServiceBus 丢失消息的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9778954/