IWantToRunWhenBusStartsAndStops不用于制作?

时间:2015-06-29 16:56:11

标签: nservicebus

NServiceBus(4.7.5)的新手,刚刚实现了一个NSB host.exe托管服务(实现IWantToRunWhenBusStartsAndStops),该服务检测数据库表的更改并通过发布事件通知订阅的Web应用程序,例如: “CustomerDataWasUpdatedEvent”。将来我们将通过显示接收命令的消息处理程序来执行实际更新,但此时此发布服务只是轮询数据库等。

这一切都运作良好,然而,接近生产,我注意到David Boike在他的最新版“Learning NServiceBus”中指出实施的课程 IWantToRunWhenBusStartsAndStops主要用于开发,很少用于生产。我在Start方法中设置了数据库更改检测,它运行良好,是否有人知道为什么不鼓励这样做?

这是实际书中的评论:

https://books.google.se/books?id=rvpzBgAAQBAJ&pg=PA110&lpg=PA110&dq=nservicebus+iwanttorunwhenbusstartsandstops+in+production+david+boike&source=bl&ots=U6sNII0nm3&sig=qIXffOVFhcy-_3qDnSExRpwRlD4&hl=sv&sa=X&ei=lHWRVc2_BKrWywPB65fIBw&ved=0CBsQ6AEwAA#v=onepage&q=nservicebus%20iwanttorunwhenbusstartsandstops%20in%20production%20david%20boike&f=false

2 个答案:

答案 0 :(得分:4)

实际报价是:

  

......在生产系统中广泛使用并不常见。

罕见与劝阻不是一回事。

那说我确实认为作者有意在突出这样一个事实,即他们断言这不是一个做大量编码的好地方,因为未处理的异常会导致整个过程失败。

作者确实继续提到一个可能的用例,当你可能想要加载资源以在处理程序中完成工作时。

  

好吧,也许只是这种情况我们有点不常见

同意 - 你的方法没有根本的错误。我最近做了与你相同的事情,用于连接SqlDependency以侦听数据库事件,然后发布消息作为结果。在这些场景中,除了使用IWantToRunAtStatup之外,除了使用IWantToRunAtStatup之外别无他法。

此外,David自己经常搜索nservicebus标签,也许他会提供比我更明确的答案。

答案 1 :(得分:3)

我将复制我在Particular Software Google Group ...

中给出的答案

我会在这里直接引用自己:

  

IWantToRunWhenBusStartsAndStops的实现是一个创建快速界面的好地方,以便在调试期间通过允许您根据控制台输入发送消息来测试消息。除此之外,在生产系统中广泛使用它们并不常见。一个可能的生产用例是在启动时配置端点所需的资源,然后在端点停止时将其拆除。

我认为如果我可以加一点强调那就是“广泛使用”。我不是说你不会/不能在生产代码中拥有IWantToRunWhenBusStartsAndStops,或者避免它们是最佳实践。我想说,拥有它们可能是一种代码味道。

在本书的那一段之上,我警告IWantToRunWhenBusStartsAndStops没有任何环境事务或尝试/捕获正在进行的事情。这真的是关键部分。如果您最终在IWantToRunWhenBusStartsAndStops中抛出异常,则可能会遇到大问题。如果您使用类似.NET计时器之类的东西然后抛出异常,则可能会导致进程崩溃!

让我告诉你我是如何在我的第一个NServiceBus系统中搞砸了这个。该系统(目前仍在使用,从我听到的内容)负责将3000多个RSS源(可能比现在多得多)摄入CMS。因此,处理每个Feed,将其分解为项目,调整图像大小,为移动设备编写附加视频......所有这些都是在NServiceBus消息处理程序中处理的,这些处理程序已扩展到多个服务器,这一切都非常棒。

问题是调度程序。我将其实现为IWantToRunWhenBusStartsAndStops(当时实际上是IWantToRunAtStartup),它很快就变成了一团糟。我将整个表格保存在内存中,以便我可以计算何时触发下一个ProcessFeed命令。我正在使用.NET Timer类和IIRC,我最终不得不使用像ManualResetEvent这样的线程原语来协调活动。因为我使用的是.NET Timer,如果调度程序引发异常,那么该端点失败并且必须重新启动。很多奇怪的边缘情况,它总是一个错误的泥潭。此外,现在这是一个单独的“指挥官应用程序”,所以虽然可以扩展饲料/项目处理器,但调度程序不能。

随着我对NServiceBus更有经验,我意识到每个feed应该是一个传奇,从FeedCreated事件开始,通过PauseProcessing和ResumeProcessing命令控制,使用超时来控制下一个处理时间,最后(也许)结束通过FeedRemoved事件。这将更加直截了当,所有内容都将在事务控制的消息处理程序中执行。

这种经历让我对IWantToRunWhenBusStartsAndStops有点不信任/持怀疑态度。不是说这很糟糕,只是需要注意的事情。总是要准备好考虑你想要做的事情是否能以另一种方式更好地完成。