http://msdn.microsoft.com/zh-cn/library/ms978706.aspx
上下文
許多複雜的軟體系統運行在多個處理器或分散式運算機上。將軟體分布在多台電腦上的原因有多種,例如:
分布式系統可以利用多個 CPU 或一群低成本電腦的計算能力。
某個軟體可能僅在特定電腦上可用。
出於安全考慮,軟體的各部分可能必須運行在不同的網段上。
一些服務可能是由業務夥伴提供的,並且只能通過 Internet 進行訪問。
但是,實現分布式系統是不容易的,因為您必須處理諸如並發性、跨平台串連和不可靠網路連接之類的問題。
問題
如何構建分布式系統以便應用程式開發人員不必關心遠程通訊的細節?
影響因素
在構建分布式系統時,必須協調下列影響因素:
雖然分布式系統具有許多優點,但是它們往往也會使軟體系統變得很複雜。運行在同一網路上的進程或電腦之間存在物理的和邏輯的邊界。要使運行在不同進程或電腦上的對象跨越這些邊界相互連信,您必須處理諸如通訊、編碼和安全之類的問題。如果您將這些實現細節與應用程式代碼混合在一起,則通訊基礎結構中的簡單更改就會導致大量的代碼更改。
在開發完成之後,通常需要分布系統。例如,可能將軟體分布在多台伺服器上以提高處理能力。您不會希望在生命週期中如此晚的階段更改應用程式代碼。
跨進程通訊的細節可能是相當乏味的。您必須處理 TCP/IP 通訊端、封送和拆收、序列化、逾時和許多其他難題。因此,有必要讓一個特殊的工作群組致力於處理基礎結構,以便讓應用程式開發人員不必瞭解遠程通訊。
要維護能夠在部署時將組件移動到不同位置這一靈活性,您必須避免對具體組件的位置進行寫入程式碼。
解決方案
使用 Broker 模式可以隱藏遠程服務調用的實現細節,方法是將這些細節封裝到一個與業務組件自身不同的層 [Buschmann96]。
這個層為用戶端提供一個介面,使用戶端可以像調用任何本地介面一樣調用方法。但是,用戶端介面內的方法會觸發要對遠程對象執行的服務。這對用戶端是透明的,因為遠程服務物件實現了相同的介面。該模式將啟動遠程服務調用的業務組件當作"用戶端",而將響應遠程服務調用的組件當作"伺服器"。
圖 1 顯示沒有進行任何分布的簡單樣本的靜態結構。用戶端直接調用伺服器上的 performFunctionA 方法。僅當伺服器對象與用戶端對象駐留在同一台電腦上時,才能發生這種情況。
圖 1:
沒有實現分布的結構
圖 2 顯示實現分布後的靜態結構。
圖 2:
實現分布後的結構
ServiceInterface 是一個必需的抽象,對於在伺服器端不必公開實現細節的情況下將由伺服器提供的服務來說,這樣的抽象可以通過提供有關該服務的和約而使分布成為可能。在實現分布時,將添加用戶端和伺服器代理,以處理通過網路將方法調用及其參數發送到伺服器,然後將響應發回用戶端的所有傳送工作。代理將完成所有資料封送和拆收、安全控制、傳輸通道配置和任何其他附加工作。用戶端只需調用用戶端代理的
performFunctionA 方法,就像它是本地調用一樣,這是因為用戶端代理實際上實現的是 ServerInterface。對用戶端進行的代碼更改將是最低限度的,因此您可以開發整個業務領域模型,而不必知道系統是否是分布式的。對遠程服務調用的實現方式的任何更改都將被限制在代理類以內,並且不會對領域模型產生任何影響。圖 3 顯示這些組件之間的一種互動方案。
圖 3:
實現分布後的行為
伺服器尋找
Broker 解決方案所針對的是前面所述的大多數問題。但是,因為用戶端代理直接與伺服器代理進行通訊,所以用戶端必須能夠在編譯時間找到伺服器的位置。這意味著,您不能在運行時將伺服器更改或移動到不同位置。要克服這一限制,需要避免公開伺服器的確切位置。而應當將新組件(即代理程式組件)部署在一個眾所周知的位置,然後向用戶端公開該位置。此後,代理程式組件負責為用戶端尋找伺服器。代理程式組件還會實現一個用於添加和刪除伺服器組件的儲存庫,這樣就有可能在運行時添加、刪除或交換伺服器組件。圖 4 顯示包含代理程式組件的靜態結構。
這種類型的功能通常稱為"名稱服務"。尋找遠程對象是企業計算中的一項常見要求。因此,許多平台實現了名稱服務,例如,Microsoft 使用 Active Directory® 目錄服務。
圖 4:
具有伺服器尋找功能的代理程式結構
代理程式駐留在一個不應該頻繁更改的、眾所周知的位置。已被啟用並且準備接收請求的任何伺服器都將向代理程式註冊自己,以便下一次用戶端向代理程式請求這種類型的伺服器時,代理程式能夠使用它。這還可能提高系統的效能和可用性,因為它使您可以擁有多個同時運行並服務於多個用戶端的、完全相同的伺服器組件。這種機制有時稱為Server Load Balancer。圖 5 顯示了一個這些組件之間的互動方案樣本。
圖 5:
具有伺服器尋找功能的代理程式行為
代理程式作為中介
在前面的方案中,代理程式僅負責為用戶端尋找伺服器。這種方案中,用戶端從代理程式獲得伺服器的位置,然後在不涉及代理程式的情況下直接與伺服器進行通訊。但是,在某些情況下,我們並不希望用戶端與伺服器之間進行直接通訊。例如,由於安全原因,您可能希望將所有伺服器放在位於防火牆後面的公司專用網路中,並且只允許代理程式訪問它們。這種情況下,您必須讓代理程式轉寄伺服器和用戶端這二者之間的所有請求和響應,而不是讓它們直接相互連信。圖 6 顯示將此模型修訂後的靜態結構。
圖 6:
用作中介的代理程式的結構
圖 7 顯示用作用戶端和伺服器之間的信使的代理程式的互動圖。此樣本還說明了用戶端和伺服器之間的通訊可以是非同步(注意 sendRequest
調用上的開放箭頭)。
也存在這樣的情況:用戶端必須對同一伺服器進行一系列方法調用,才能完成一個期間長而且複雜的業務事務。在這樣的情況中,伺服器必須在前後用戶端調用之間保持狀態不變。然後,代理程式必須確保用戶端在基本會話內所進行的所有伺服器調用都會被路由到完全相同的伺服器組件。
圖 7:
用作中介的代理程式的行為 返回頁首
樣本
Broker 模式及其變體在許多分布式系統架構中得到實現。請參閱使用伺服器啟用物件通過 .NET Remoting 實現 Broker 和使用用戶端啟用物件通過 .NET Remoting 實現 Broker。
結果上下文
Broker 模式具有
Layered Application 模式的許多優點和缺點。
優點
Broker 具有下列優點:
隔離。通過將所有與通訊有關的代碼分離到它自己的層中,從而使其與應用程式隔離。您可以決定在不必更改任何應用程式代碼的情況下以分布方式運行應用程式,或者在一台電腦上運行全部應用程式。
簡單。將複雜的通訊邏輯封裝到單獨的層中,可以使問題變得更簡單。為代理程式編寫代碼的工程師不必關心無法預知的使用者要求和商務邏輯,而應用程式開發人員也不必關心多播協議和 TCP/IP 路由。
靈活。通過將多個函數封裝在一個層中,可以允許您以不同的實現來交換該層。例如,您可以從 DCOM 切換到 .NET Remoting,再切換到標準 Web Service,而不用更改應用程式代碼。
缺點
可惜的是,抽象層可以損害效能。基本規則是,擁有的資訊越多,就可以最佳化得越好。使用單獨的代理程式層可能隱藏有關應用程式如何使用較低層的細節,這可能又會阻止較低層執行特定的最佳化操作。例如,使用 TCP/IP 時,路由協議不知道正在路由的是什麼資料包。因此,很難決定包含視頻流的資料包(例如)應該具有比包含垃圾郵件的資料包更高的路由優先順序。
安全考慮事項
包含敏感業務資料的伺服器組件通常位於公司的專用網路中,並受到防火牆的保護。而代理程式位於周邊網路(也稱為非管制區 (DMZ) 或屏蔽子網)中,周邊網路是作為公司專用網路與外部公用網路之間的中性地區而插入的小型網路。只允許從周邊網路訪問伺服器組件,而不允許從外部公用網路訪問這些組件。這一額外的網路層阻止了外部使用者直接存取伺服器。