2015-06-29 67 views
3

對NServiceBus(4.7.5)不熟悉,只是實現了一個NSB host.exe託管服務(實現IWantToRunWhenBusStartsAndStops),該服務檢測數據庫表的更改並通過發佈事件通知訂閱的Web應用程序。 「CustomerDataWasUpdatedEvent」。今後,我們將通過執行接收命令顯然messagehandlers實際的更新,不過目前這個發佈服務只是輪詢數據庫等IWantToRunWhenBusStarts並停止生產?

這一切運作良好,但是,臨近生產,我注意到,大衛Boike,在他最新版本的「學習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

回答

3

我會複製我在Particular Software Google Group給出了答案......


我會在這裏直接引用自己:

IWantToRunWhenBusStartsAndStops的實現是一個偉大的地方創建快速接口,以便在調試期間通過允許您基於控制檯輸入發送消息來測試消息。除此之外,在生產系統中廣泛使用它們並不常見。一個可能的生產用例是在啓動時配置端點所需的資源,然後在端點停止時將其分解。

我想如果我可以加上一點點的重點,那就是「廣泛使用」。我並不是說你不會/不能在生產代碼中使用IWantToRunWhenBusStartsAndStops,或者避免使用它們是最佳做法。我想說,有一噸他們可能是代碼味道。

在本書的以上段落中,我警告IWantToRunWhenBusStartsAndStops沒有任何環境事務或嘗試/捕捉正在發生的事情。這實際上是關鍵部分。如果最終在IWantToRunWhenBusStartsAndStops中拋出異常,則可能會遇到大問題。如果您使用類似於.NET Timer的東西,然後拋出異常,則可能會導致進程崩潰!

讓我告訴你我是如何在我的第一個NServiceBus系統中搞砸的。該系統(今天仍在使用,據我所知)負責將超過3000個RSS源(可能比現在多得多)攝入CMS。因此,處理每個Feed,將其分解爲多個項目,調整圖像大小,爲移動設備編碼附加視頻......所有這些事情都在NServiceBus消息處理程序中處理,這些消息處理程序已擴展到多個服務器,這一切都非常棒。

問題在於調度程序。我將它作爲IWantToRunWhenBusStartsAndStops(當時實際上是IWantToRunAtStartup)實現,並且很快變成了一團糟。我在內存中保存了整個表格的供給信息,以便我可以計算何時啓動下一個ProcessFeed命令。我使用的是.NET Timer類和IIRC,我最終必須使用線程原語(如ManualResetEvent)來協調活動。而且,因爲我使用的是.NET Timer,所以如果調度程序引發異常,則該端點失敗並且必須重新啓動。很多奇怪的邊緣情況,它總是一個bug的泥潭。此外,這是一個單身的「指揮官應用程序」,所以雖然飼料/物品處理器可以擴展,但調度程序不能。由於我對NServiceBus有了更多的經驗,我意識到每個feed應該是一個傳奇,從FeedCreated事件開始,通過PauseProcessing和ResumeProcessing命令控制,使用超時控制下一個處理時間,最後(可能)通過FeedRemoved事件結束。這將會更直接,並且所有事情都會在事務控制的消息處理程序中執行。

這個經歷讓我對IWantToRunWhenBusStarts和Stop有點懷疑/懷疑。不是說它不好,只是要注意的一點。永遠要準備好考慮你想要做什麼不能以另一種方式更好地完成。

4

的實際報價是:

...這是不常見的有在生產系統中廣泛使用的。

不尋常的事情與氣餒不同。

這就是說,我認爲作者在這裏強調這一事實,即進一步在頁面上他們斷言這不是一個很好的地方做大量的編碼,因爲未處理的異常會導致整個過程失敗。

作者實際上接着提到一個可能的用例,用於何時可能需要加載資源以在處理程序中執行工作。

好吧,也許它只是這種情況下,我們有就是有點少見

同意 - 有什麼根本性的錯誤你的方法。我最近和你做了同樣的事情來連接SqlDependency來監聽數據庫事件,然後發佈消息。在這些場景中,除了使用IWantToRunAtStatup之外,其他任何事情都可以做到。另外,大衛本人經常拖網nservicebus標籤,也許他會提供比我更明確的答案。

+0

好吧,也許這只是我們有這種情況,有點不尋常。通常情況下,數據庫插入(這是更多的批處理情況,比被某些業務相關的事件更改的實體更多)將通過在NSB託管服務內運行的命令處理程序,在這種情況下,IWantToRunWhenBusStartsAndStops.Start方法只會執行初始化當然,實際工作(更新數據庫和發佈事件)將在處理程序中完成。 – Ale

+0

@Ale - 請參閱我的編輯 –

+0

+1。我認爲你的用例不常見 - 我猜你是通過調度程序作爲控制檯應用程序運行的?如果是這樣,我認爲它本身與作爲Windows服務運行相比並不常見。他在該鏈接段落中的最後一句正好描述了我在生產中使用IWantToRunWhenBusStartsAndStops:調配資源或啓動後臺進程。當前的一個例子是啓動自託管的WebAPI。 –

相關問題