目錄
SOA是一種通過為所有軟體提供服務外觀,並將這些服務的WSDL集中釋出到一個地方的一種組織企業軟體的方法。它通過使用明確定義的介面通過跨越邊界傳遞訊息來讓多個自治的服務協同工作。SOA的真正價值是——允許開發者從程式碼中抽取出公共基礎功能的實現,更多地關注業務邏輯和需要的功能特性。在開發SOA應用程式時,我們能夠實現服務程式碼與客戶端使用技術與平臺的解耦,也與併發管理、事務傳播和管理以及通訊可靠性、協議和模式無關。
SOA的4個主要設計原則以及在WCF中的具現如下:
- 邊界是明確的 SOA系統中的每個服務都必須被限定在某個明確的邊界之內。服務邊界指的就是服務的公共介面與其內部實現之間有清晰的界線。WCF服務的功能是通過定義明確的介面進行表達的,外部呼叫者和WCF服務通訊的唯一方式就是通過這個介面,客戶端無法知道服務的實現細節,以達到資訊隱藏和解耦的目的。
- 服務是自治的 自治的服務對於版本問題、部署問題和安裝問題來說應該是獨立的不會影響整個SOA系統。服務的執行不需要依賴任何外部服務或者元件。我們為WCF擴充套件功能,只能通過編寫新的介面來實現。
- 採用標準的契約定義和通訊協議 服務通過契約而不是實現進行通訊,服務契約定義和通訊協議都是行業標準。WCF對常用協議和主流編碼格式提供支援。
- 服務是自解釋的 服務的內容必須是自解釋的,服務必須以某種方式告訴客戶端服務的功能。WCF提供了強型別的契約,並會根據繫結來生成WSDL文件。
以上原則比較抽象,為了更好的設計SOA程式,應該遵守以下原則:
- 服務是安全的 服務與客戶端必須使用安全的通訊。
- 服務在系統中應保持一致的狀態 執行客戶端請求時,禁止進行部分替換條件,即系統提供服務給客戶端呼叫後必須保持一致的狀態,如果有錯誤發生,系統狀態不應該部分受到影響,必須被恢復到一致的狀態。
- 服務是執行緒安全的 服務必須設計為執行緒安全,才能維持多執行緒的併發訪問。
- 服務是可靠的 客戶端以確定的方式獲知服務是否接收了訊息。
- 服務是健壯的 服務與它的錯誤分離能夠防止錯誤影響服務本身或其它服務。
可選原則如下:
- 服務是平臺無關的 服務應該能夠被任意的客戶端呼叫,而不用考慮客戶端技術。
- 服務的規模不可變 不管客戶端有多少,也不管服務的承載是多少,服務程式碼都應該相同。
- 服務是可用的 服務總是能夠接受客戶端的請求,而不會因此停止。
- 服務是及時響應的和受限的 服務開始處理客戶端的請求時,不能讓客戶端等待的太久。服務執行的任意操作應該儘可能短,不能消耗太多時間去處理客戶端的請求。
微軟的WCF框架中的基礎設施為我們解決了以上原則中的多數,使我們可以將關注點重新迴歸的業務邏輯層上。面向服務技術展示出的魅力,促使越來越多的開發者投入其中。
WCF的體系架構如下:
WCF的客戶端與服務端模型如下:
1 地址
WCF的每一個服務都有唯一的地址。地址包括服務位置和傳輸協議(傳輸樣式)。服務位置包括目標機器名、站點、網路、埠、管道或佇列,以及一個可選的特定路徑或者URI。
地址常用格式為:[基地址]/[可選的URI],如“net.tcp://localhost:8081/MyService”。
基地址常用格式為:[傳輸協議]://[機器名或域名][:可選埠],如“net.tcp://localhost:8081”。
WCF支援多種傳輸樣式:
- HTTP 採用http、https協議進行傳輸,預設埠號80。
- TCP 採用net.tcp協議進行傳輸,預設地址為808。
- Peer network(對等網) 採用net.p2p進行傳輸,採用Windows的對等網傳輸機制。
- IPC(內部程式通訊) 採用net.pipe進行傳輸,使用Windows的命名管道機制,只能接收來自同一臺機器的呼叫,且每臺機器只能開啟一個命名管道。
- MSMQ 採用net.msmq進行傳輸,使用Windows的MSMQ機制,必須指定佇列名,如果是處理私有佇列,則必須指定佇列型別。
2 繫結
繫結將通訊模式與互動方式直接的組合進行規範,將這些通訊特徵合理地組合在一起。一個繫結封裝了諸如傳輸協議、訊息編碼、可靠性、安全性、事務傳播以及互操作性等相關選項的組合,使得它們保持一致。
WCF定義了六種常用的繫結:
- 基本繫結 由BasicHttpBinding類提供,將WCF服務公開為Web服務。
- TCP繫結 由NetTcpBinding類提供,使用TCP協議通訊,支援多種特性,包括可靠性、事務性、安全性及WCF之間通訊的優化,缺點是客戶端必須使用WCF。
- IPC繫結 由NetNamedPipeBinding類提供,使用命名管道為同一機器的通訊進行傳輸,支援的特性與TCP繫結類似,是效能和安全性最佳的繫結。
- Web服務繫結 由WSHttpBinding類提供,WS繫結使用HTTP或HTTPS進行傳輸,提供了諸如可靠性、事務性與安全性在內的多種特性,這些特性遵循WS-*標準,該繫結被設計用來與支援WS-*標準的系統進行互操作。
- WS雙向繫結 由WSDualHttpBinding類提供,支援雙向通訊。
- MSMQ繫結 由NetMsmqBinding類提供,使用MSMQ進行傳輸。
常用繫結的傳輸協議與編碼格式如下:
名字 | 傳輸協議 | 編碼格式 | 互操作性 |
BasicHttpBinding | HTTP/HTTPS | Text,MTOM | yes |
NetTcpBinding | TCP | Binary | no |
NetNamedPipeBinding | IPC | Binary | no |
WSHttpBinding | HTTP/HTTPS | Text,MTOM | yes |
WSDualHttpBinding | HTTP | Text,MTOM | no |
NetMsmqBinding | MSMQ | Binary | no |
注意:TCP、IPC和MSMQ繫結使用的二進位制編碼器是WCF專有的,不要試圖為其編寫針對其他平臺的自定義解析器。
3 契約
WCF的所有服務都公開為契約,契約與平臺無關,是描述服務功能的標準方式。WCF包含4類契約:
- 服務契約 描述了客戶端能夠執行的服務操作。
- 資料契約 定義了與服務互動的資料型別。
- 錯誤契約 定義了服務丟擲的錯誤,以及服務處理錯誤和傳遞錯誤到客戶端的方式。
- 訊息契約 訊息契約允許服務直接與訊息互動,用於定製專有的訊息格式,也意味著要自己的應用程式上下文,因為會增加程式碼的複雜度,所以不屬於常見用法。
4 終結點
終結點是WCF進行通訊的唯一手段,ChannelFactory<T>本質上是通過制定的終結點建立用於進行服務呼叫的服務代理。終結點在WCF體系中通過Systtm.ServiceModel.Description.ServiceEndpoint型別表示,其包含三個核心屬性——地址、繫結、契約。終結點是用來傳送和接收訊息的構造,終結點是真正意義上的介面,它包含了一個物件介面所需的全部資訊。每個服務至少必須公開一個業務終結點,每個終結點有且只能擁有一個契約。服務上的所有終結點都包含了唯一的地址,而一個單獨的服務則可以公開多個終結點。這些結點可以使用相同或不同的繫結,公開相同或不同的契約。
5 後設資料
服務的後設資料描述服務的特徵,外部實體需要了解這些特徵以便與該服務進行通訊。服務的後設資料包括XML、架構文件(用於定義服務的資料協定)和WSDL文件(用於描述服務的方法)。啟用後設資料後,WCF通過檢查服務及其終結點自動生成服務的後設資料。
6 上下文
WCF上下文將服務宿主與公開本地CLR型別為服務的上下文組合在一起,上下文是服務例項最核心的執行範圍,上下文可以為空,即不包含任何服務例項。
7 宿主
WCF服務類不能憑空存在,每個WCF服務類必須託管在某個宿主程式中。單個宿主程式可以託管多個服務,而相同的服務型別也可以託管在多個宿主程式中,如果服務與客戶端駐留在相同的程式中,則稱為程式內託管。常用宿主如下:
- Web站點
- Windows窗體應用程式
- Windows服務
- Windows啟用服務(WAS)
WCF宿主體系結構如下:
每個.NET宿主程式都包含了多個應用程式域,每個應用程式域包含零到多個宿主例項,每個服務宿主例項專門對於於一個特殊的服務型別。因此,建立一個宿主例項,實際上就是為對應於基地址的宿主機器的型別註冊一個包含了所有終結點的服務宿主例項。每個服務宿主例項擁有零到多個上下文。一個上下文可以與零個或一個服務例項關聯。
8 代理
WCF不允許客戶端直接與服務互動,客戶端使用代理將呼叫轉發給服務。即使物件是本地的,WCF仍然使用遠端程式設計模型的例項化方式,並且使用代理。
(一) 通道棧模型
WCF通道模型:
無論互動的另一方的具體位置在哪裡,WCF都會為訊息的傳送和接收建立一套完整的訊息管道,這個訊息管道被成為通道棧。通道棧中的每一個通道元件都有機會對訊息進行處理,而整個通道棧是可編輯且可插入的,這就確保WCF的通道模型具有相當大的靈活性。另外,WCF通道模型是完全和上層程式隔離的,任何一個服務/客戶端都可以輕鬆配置到不同的通道模型上去。通道模型可以被分為兩部分——協議通道和傳輸通道。一個通道棧可以擁有任意多個協議通道,但一般只擁有一個傳輸通道。傳輸通道負責把訊息進行編碼並且傳送到遠端,編碼時需要使用呼叫棧的編碼器。一般而言,協議通道負責維護訊息的非業務邏輯功能,包括:事務、日誌、可靠訊息、安全性等。開發者可以自定義協議通道並插入到通道棧中。在一個通道棧中,必須包含至少一個傳輸通道和編碼器,傳輸通道負責把訊息編碼和傳送。(傳輸通道會嘗試從BindingContext物件中查詢編碼器,如果沒有找到則會使用預設的編碼器,在完成訊息的編碼之後,傳輸通道負責把訊息傳送到遠端,不同的傳輸通道將使用不同的傳輸協議,如HTTP、TCP、IPC等。)
WCF體系體系架構是基於攔截機制的,通過代理與客戶端的互動意味著WCF總是處於服務與客戶端之間,攔截所有的呼叫,執行呼叫前和呼叫後的處理。當代理將呼叫棧幀序列化到訊息中,並將訊息通過通道鏈向下傳遞時,WCF就開始執行攔截。通道相當於一個攔截器,目的在於執行一個特定的任務。每個客戶端通道都會執行訊息的呼叫前處理。鏈的組成與結構主要依賴於繫結。客戶端的最後一個通道是傳輸通道,根據配置的傳輸方式傳送訊息給宿主。在宿主端,訊息同樣通過通道鏈進行傳輸,它會對訊息執行宿主端的呼叫前處理。宿主端的第一個通道是傳輸通道,接收傳輸過來的訊息。隨後的通道執行不同的任務。宿主端的最後一個通道負責將訊息傳遞給分發器。分發器將訊息轉換到一個棧幀,並呼叫服務例項。事實上,服務會被本地客戶端——分發器呼叫。客戶端與服務端的攔截器確保了它們能夠獲得執行時環境,以便於它們執行正確的操作。
服務例項會執行呼叫,然後將控制權返回給分發器。分發器負責將返回值以及錯誤資訊轉換為一條返回訊息。分發器獲得控制權,執行的過程剛好相反:分發器通過宿主端通道傳遞訊息,執行呼叫後的處理,如管理事務、加密等。為了執行客戶端呼叫後的處理,包括解密、解碼、提交或取消事務等任務,傳輸通道會將返回訊息傳送到客戶端通道。最後一個通道將訊息傳遞給代理。代理將返回訊息轉化到棧幀,然後將控制權返回給客戶端。
(二) 訊息交換模式
WCF定義的6種訊息交換模式:
1 請求-響應模式
客戶端向伺服器傳送一個請求,等待伺服器的響應,等待時間是一個預定義的時間,是最常用的模式。WCF中通過在介面上定義[ServiceContact]和[OperationContract]來表示請求和響應的細節。
2 單工訊息處理模式
只按一個方向把訊息從客戶端傳送到伺服器,伺服器只處理訊息,但不返回處理結果。這種模式最大的價值在於能夠實現非同步通訊以及保證訊息傳送環境的能力,利用單工模式,可以通過MSMQ來傳送訊息。WCF通過把[OperationContract]的IsOneWay設定為True,來實現單工模式。
3 雙工訊息處理模式
客戶端和服務端相互呼叫,客戶端和服務端的角色也在不斷交替。為了完成回撥,服務端必須知道回撥操作的方法簽名,而且該回撥操作將同時出現在客戶端和服務端中。為此,在WCF中實現雙工模式,需要在它的繫結資訊中說明,在客戶端實現的方法簽名需要在服務層定義,同時需要這些方法在客戶端實現,這樣服務端才能呼叫他們。
4 流模式
客戶端發起一個請求,請求一個非常大的資料,服務把資料分割為小塊,並把這些資料塊按使用順序逐個地傳送給客戶端。在這種模式下,一個資料請求緊跟著多個響應,每個響應都包含了全部資料的一個子集,由傳送者在最後的訊息中標識資料流的結束,以告知客戶端不需要繼續等待更多的資料。
5 釋出-訂閱模式
釋出-訂閱模式中,釋出者不關心是否有訂閱者,它只關心從自己的系統中傳送資料。這種模式表示了一種驅動方法,即釋出者在客戶端應用程式中啟動一個事件,客戶端針對這些事件作出響應。WCF不直接支援釋出-訂閱模式,而是利用與雙工模式相同的構造來實現釋出-訂閱模式。釋出-訂閱模式的實現通過一個訂閱服務,此服務在記憶體中儲存訂閱者回撥通道的引用。當服務需要向所有訂閱者傳送資料時,它便迴圈地訪問這些訂閱者,並呼叫一個方法來傳送資料。這裡沒有使用輪詢的方法,是因為訂閱者起宿主的作用,它在等待被服務呼叫的方法。
6 隱式順序呼叫模式
在該模式中,客戶端以某個順序呼叫服務端的多個操作。隱式順序呼叫模式允許定義邏輯順序中最後呼叫的方法,此後客戶端將不能再呼叫其它方法。WCF使用[OperationContract]定義操作的呼叫順序,把方法的IsInitiating設定為false,可以起動一個會話;把IsTerminating設定為true,表示呼叫這個方法以結束會話。(另一種實現方式,是藉助工作流。)
(三) 通道形狀
WCF中通過通道形狀來實現具體的訊息交換模式,通道形狀則是隻繼承自IChannel的一組介面,WCF會根據上層協議來自動選取需要的通道形狀。訊息交換模式與通訊協議是密切相關的,通過在傳輸通道上層新增特殊的協議通道,可以強制使用某種傳輸通道不支援的訊息交換模式。(OneWayBindingElement單工模式和CompositeDuplexElement雙工模式)
(四) 通道管理器
WCF中實現了兩類通道管理器,分別實現IChannelListener<T>和IChannelFactory<T>。IChannelListener<T>負責接收端的資訊交換控制工作,負責偵聽訊息、建立通道棧,並且通過通道棧頂層通道的引用,它可以獨立於它的通道棧而關閉。ServiceHost內部就是使用了IChannelListener<T>來實現通道的管理。IChannelListener<T>負責在傳送端控制訊息的傳送以及建立並管理通道棧,並且負責關閉通道棧,一般使用ClientBase<T>來代替直接使用IChannelFactory<T>。
(五)ICommunicationObject
WCF的ICommunicationObject定義了狀態機制的統一模型。基本所有的通訊元件,包括通道和通道管理器都實現了ICommunicationObject。ICommunicationObject用於狀態管理,其定義了改變狀態的方法、狀態改變觸發的事件已經當前狀態的獲取。ICommunicationObject的State為CommunicationState列舉型別,用於表示“狀態”,有6種可用狀態,分別為:Created(已建立),Opening(開啟中),Opened(已開啟),Closing(關閉中),Closed(已關閉),Faulted(錯誤),其狀態變化順序如下:
由上圖可見,狀態機的改變是隻進的,狀態的改變是不可逆的。
- 使用.NET介面定義契約。
- 編寫實現契約的服務類。
- 新增相應特性對WCF的行為進行控制。
- 開發宿主程式承載服務。
- 設定服務端配置檔案,定製個性化需要。
- 客戶端新增服務引用,生成代理類。
- 設定客戶端配置檔案,定製個性化需要。
- 應該將服務程式碼放入到類庫中,而不是放到宿主程式中。
- 不要為服務型別提供帶引數的構造器,除非託管的服務是明確的單例服務。
- 在相關繫結中啟用可靠性。
- 為契約提供有意義的名稱空間。
- 對於執行在Windows XP或Windows Server 2003上的區域網應用程式,最好選用自託管,而不是IIS託管。
- 在Windows Vista和Windows Server 2008或更高版本中,最好使用WAS託管,而不是自託管。
- 啟用後設資料交換。
- 為客戶端配置檔案中的所有終結點命名。
- 儘量自己編寫配置檔案。
- 不要複製代理的程式碼,可以將代理分解到單獨的類庫中。
- 及時關閉和釋放代理。
作者:MeteorSeed
感謝您閱讀本文,如果您覺得有所收穫,麻煩點一下右邊的“推薦”,您的支援是對我最大的鼓勵...
轉載請註明出處。
轉自http://www.cnblogs.com/MeteorSeed/archive/2012/04/24/2399455.html