2013-02-19 523 views
3

我有三個wcf服務A,B和C,因爲我希望它是SOA(面向服務的體系結構),我的設置工作的方式是當我從客戶端向服務器發送請求時。WCF服務依賴關係

  1. 所有的服務都是自我託管的Windows服務。
  2. 客戶端發送請求到服務A(客戶端不知道其他服務B和C);
  3. 服務A最終發送該請求到服務B和服務C.
  4. 服務B和C發送響應返回給服務A這將由服務A.

問題IM被髮送回客戶端面臨:如果我在服務B的代碼進行任何更改並重建並重新啓動服務,我有問題獲取響應,但當我重新啓動所有其餘的服務,然後它工作正常。

換句話說,我的客戶端沒有得到響應,除非我重新啓動所有的服務(A,B和C),即使我只是在一個服務中更改了代碼並重新構建了它。我知道如果我重新啓動所有三個服務,但我想知道這是我的設計方式的問題,或者這是我必須處理自我託管的Windows服務。所有的服務(A,B,C)是獨立的,因爲沒有任何依賴彼此。

有沒有人見過這樣的事情發生在SOA中。我會很高興,如果有人能指導我適當的解決方案?

+0

如果版本包括版本號,並將其存儲在客戶端上生成的代理,這可以解釋爲什麼你要刷新/重建代理。 – 2013-02-19 21:50:59

+0

您應該記錄並研究您聲稱擁有的問題。是否拋出異常?服務使用哪些綁定? – CodeCaster 2013-02-19 23:46:28

回答

3
  1. 用任何類型的隊列替換服務之間的WCF(一個服務發佈的東西,其他可以讀取時,他們準備好了)。可以是任何東西。可以是一個簡單的表格,如果有新的東西,你可以從中讀取。可以是RabbitMQ,NServiceBus等,無論適用於您。

  2. 定義你把隊列中的消息:命令和事件。兩者都是具有屬性的簡單類,沒有邏輯。命令表示系統要求做什麼(RegisterUser,PlaceOrder等),事件表示系統已完成的操作(UserRegistered,OrderApproved,PaymentReceived等)。明確說明動作,不要做類似於「我已更改客戶端上的所有用戶屬性,現在我調用SaveUser(用戶)」的內容。 您的服務設知道如何改變的對象,客戶只能指揮什麼做。

  3. 永遠不會破壞你的合同。這很容易,比聽起來容易:您可以添加東西到您的消息合約,但無法刪除。換句話說,你只需保持你的合同向後兼容。

現在你有一個更好的設計:服務只通過隊列中的消息進行通信,消息是向後兼容的。這意味着您可以隨時停止任何服務而不會影響其他服務:它們將繼續將消息發送到隊列中,並且當停止的服務再次返回時,它將趕上處理隊列中的所有內容。然後,如果你願意,你可以在客戶端交互中使用相同的方法:如果不是調用WCF客戶端,而只是將他們的命令置於某種隊列中,那麼服務升級或其他停機時間不會影響用戶體驗。

例子:如果我使用WCF來下訂單或把項目變成購物卡,然後如果有問題或服務正在維護中,我將無法做到這一點。我會點擊一個按鈕,並有一個令人討厭的錯誤。更重要的是,我的訂單不會進入系統。 相比之下,如果中間有一個隊列,我只會將我的命令放入隊列中。現在,即使我的服務目前處於關閉狀態,或者遇到高負載(因此速度較慢),那麼我的用戶體驗仍然相同,並且不會降級。這只是我的命令將稍後處理,但作爲客戶我並不在乎。我的訂單在這種情況下不會丟失。該系統變得容錯和自我平衡。

如果您只是在中間放置一個隊列,而不是遇到WCF附帶的空間和時間耦合問題,您可以使用各種各樣的奇妙技巧: 而我所描述的只是開始...... :)

1

您可能需要考慮使用服務總線(如​​)來幫助您完成功能。

它將幫助您解決的第一個問題是通過發佈/訂閱消息傳遞模式解耦您的服務。不是在一個或其他服務中調用Web服務,而是在發生事件時發佈通知相應服務的事件。在你的情況,這將是這個樣子:

  1. 客戶端調用Web服務在服務A.
  2. 服務A發佈的消息「客戶端接收到的命令」的服務B和C訂閱。
  3. 服務B和C處理此事件,然後發佈他們自己的事件。
  4. 服務A訂閱事件和對客戶端的回覆。

使用NServiceBus的第一個和直接的好處是可靠性。最重要的是,您可以輕鬆版本化您的消息,而不會影響您的客戶或您的各自服務。 NServiceBus具有完整的WCF集成,因此您的客戶端可以像以前一樣繼續向您的服務發送消息。

讓您的場景變得有趣的一件事是,您無法保證服務B和服務C何時將他們的回覆發送給您。您是否保持與客戶的連接處於打開狀態,直到Service收到他們的回覆?在您向客戶發送回覆之前,您是否需要兩種回答?如果其中一項或其中一項服務崩潰會發生什麼?如果在服務A收到回覆之前有多久可以等待的時間限制?所有這些問題以及更多問題都可以通過NServiceBus中名爲Sagas的功能來解決。一探究竟。

如果使用NServiceBus是不可能的事情變得更加困難。 WCF不支持發佈/訂閱,所以你將不得不自己烘焙。至少我會建議使用它來分離你的服務。如何管理服務中的狀態和時間耦合是另一回事。省去麻煩。

還有其他的框架存在,但如果你想有一個開發中心,成本創造那麼一個基於.NET解決方案建議使用NServiceBus有效途徑。