2012-01-16 76 views
6

如果不是所有的NSB例子爲ASP.NET(或MVC)具有Web應用程序使用Bus.Send發送消息,並可能是註冊一個簡單的回調,這基本上是我如何在我的應用程序中使用它。ASP.NET應用程序可以處理NServiceBus事件嗎?

我想知道的是,如果在同一個ASP.NET應用程序中可能和/或對句柄消息有任何意義。

主要的原因我問的是緩存。該過程可能是這樣的:

  1. 用戶從Web應用程序發起請求。
  2. Web應用程序向獨立應用程序服務器發送消息,並將更改記錄在本地數據庫中。
  3. 在來自同一用戶的未來頁面請求中,Web應用程序知道該更改並將其列爲「待處理」狀態。
  4. 一堆東西發生在後端,最終請求被批准或拒絕。參考原始請求發佈事件。
  5. 此時,Web應用程序應該開始顯示的最新信息。

現在,在一個真正的web應用程序中,這個掛起的請求將被緩存,很可能很長一段時間,因爲否則應用程序必須在數據庫中查詢掛起的更改每次用戶要求提供當前信息。

所以,當請求最終完成對後端 - 這可能需要一分鐘或一天 - Web應用程序的需求,至少,爲了無效該緩存條目,做一套DB查詢。

現在我意識到這可以通過SqlDependency對象等來管理,但是讓我們假設它們不可用 - 可能它不是SQL Server後端,或者當前信息查詢可能轉到Web服務, 隨你。問題是,Web應用程序如何意識到狀態的變化?

如果它是可能在ASP.NET應用程序中處理NServiceBus消息,那麼處理程序的上下文是什麼?換句話說,IoC容器將不得不注入一堆依賴項,但它們的範圍是什麼?這是否全部在HTTP請求的上下文中執行?還是一切都需要靜態/單身的消息處理程序?

對這類問題有更好的/推薦的方法嗎?

+0

我不知道如何處理IIS中的事件,但是無論何時您引入異步過程,您都必須處理最終的一致性。網絡應用程序是否需要立即更新,或者每分鐘15分鐘每小時刷新一次緩存? – Ryan

+0

@Ryan:我們可以逃避嗎?大概。我對客戶POV感到滿意嗎?不是真的。我對EC一般都很滿意 - 例如,我意識到,如果網站或應用程序池未運行,直到它再次啓動,並且* *完全正常 - 但信息應該已啓動在某些用戶實際請求它的幾分鐘之內,數據真的應該被緩存更長的時間。這種差異通常通過手動或基於依賴關係的緩存失效來解決。 – Aaronaught

+0

對,這就是我在我的同步應用程序中所做的。對於NSB,我只是每次都碰到數據庫,但我只有幾個用戶的後臺應用程序。 – Ryan

回答

1

端點(NSB)可以創建訂閱發佈的事件,並更新緩存。只有在實際更新完成後才能發佈該事件,以免不同步。 Web應用程序將繼續在下一個請求中從緩存中提取數據,或者可以在某種延遲中進行構建。

+0

這聽起來有點模糊,當然事件不會在事務實際發生之前發佈,但是在什麼時候它會保證到達ASP.NET應用程序中的消息處理程序?你對我關於依賴範圍的問題有任何評論嗎?我試圖理解一個消息處理程序是否可以將某個依賴項綁定到HTTP請求(Ninject - InRequestScope)上。 – Aaronaught

+0

假設它是交易型和耐用的,它將通過運輸保證。範圍將按照請求,檢查AsyncPages示例。這注冊了頁面的回調,並且正在處理消息,這聽起來好像在這種情況下足夠好。在我看來,到下一次讀取更新將會在那裏,所以你可以做一些UI的事情來幫助。這個網站的工作方式,如果你刷新足夠快的數據不存在。 –

+0

這不完全相同的情況,但我認爲這是一個很好的閱讀NSB /網絡應用程序的一些背景:http://www.make-awesome.com/2010/10/why-not-publish-nservicebus - 從Web應用程序的消息/ –

2

我不知道我自己同樣的事情 - 什麼是耦合的,用於與NServiceBus基礎設施的網絡應用適當的水平?在我的域中,我遇到了類似的問題來解決涉及使用SignalR代替緩存的問題。像你一樣,我還沒有找到關於這種特定模式的很多文檔。但是,我認爲可以通過遵循它的某些含義來推理,然後決定它是否在您的環境中有意義。

總之,我認爲完全有可能讓web應用程序訂閱NServiceBus事件。我不認爲會有任何技術性障礙,儘管我必須承認我沒有真正嘗試過 - 如果你有時間,盡一切辦法給它一個鏡頭。我只是強烈地感到,如果開始需要來做到這一點,那麼可能有更好的整體設計等待被發現。這就是爲什麼我認爲這是如此:

  1. 要問的相關問題與您的緩存實施有關。如果它是分佈式或集中式模型(比如SQL,MongoDB,Memcached等),那麼@Adam Fyles建議的方法聽起來是個好主意。您不需要需要來通知每個Web應用程序 - 更新緩存可以通過單個NServiceBus端點完成,該端點的而不是 Web應用程序的一部分。換句話說,您的Web應用程序和「緩存更新」端點的每個實例都將訪問相同的共享緩存。但是,如果你的緩存在進程中,比如微軟的Web緩存,那麼當然你需要解決一個更復雜的問題,除非你可以像建議的那樣依靠最終一致性。
  2. 如果您的Web應用程序訂閱特定的NServiceBus事件,那麼您需要爲每個Web應用程序實例分配一個唯一的輸入隊列。由於最佳做法是考慮使用負載均衡器擴展您的Web應用程序,這意味着您最終可能會有N個隊列和至少N個訂閱,這比訂閱的數量更多而不必擔心。再一次,不是技術性的障礙,只是會讓我揚起眉毛的東西。
  3. David Boike被鏈接的文章提出了一個關於應用程序池以及它們的生命週期如何不確定的有趣觀點。另外,如果您爲服務器上的同一應用程序同時運行多個應用程序池(通常情況下),則它們都將嘗試從同一個消息隊列中讀取,並且沒有好方法可以確定哪個應用程序實際處理消息。更重要的是,這很重要。相反,發送命令不需要根據this post by Udi Dahan的輸入隊列。這就是爲什麼我認爲Web應用程序發送的單向命令在實踐中更常見的原因。
  4. 這裏有很多要說的單一責任原則。一般來說,如果您可以儘可能將發送和接收消息的「專業知識」委派給NServiceBus主機,那麼您的整體架構將變得更乾淨,更易於管理。通過經驗,我發現如果我把我的網絡農場看作是一個單獨的實體,即剝奪了對個人網絡服務器身份的所有確認,那我就不用擔心了。讓每個Web服務器成爲總線上的端點類型會打破這個概念,因爲現在「哪個服務器」以消息隊列的形式再次出現。

這是否有助於澄清事情?

相關問題