構架SOA應用的10條原則
在與客戶的多次接觸中,我都需要建立一套基本的 SOA 原則。以下章節介紹了面向服務的架構(SOA)所需要遵循的基本準則。這些準則不是絕對正確的,只是一套針對SOA相關討論的框架性意見。你可能注意到前四條是基于Don Box的四項原則,只是我在經過了這么長時間
在與客戶的多次接觸中,我都需要建立一套基本的
SOA原則。以下章節介紹了面向服務的架構(SOA)所需要遵循的基本準則。這些準則不是絕對正確的,只是一套針對SOA相關討論的框架性意見。你可能注意到前四條是基于Don Box的四項原則,只是我在經過了這么長時間后加上了點個人的想法(我之所以把它們列出來是因為有人要求我提供一個可供參考的版本;我沒有回顧過這幾條,可能現在我對其中某些的看法已有改變)
1)清晰的邊界
在調用一個服務來完成它提供的功能的時候,需要將服務所需的所有信息傳遞過去。所有對服務的訪問都應通過其對外公開的接口;不應當允許某個服務存在任何隱含的假設。:“服務不可避免地要依賴消息,因為所有進出服務的東西都是消息”。通常情況下,服務的調用應該不依賴共享的上下文,而應該設計成無狀態的。服務所暴露的接口通過契約規定了它的功能性和非功能性的作用和特征。服務的調用是一個有業務意義的動作,可能是十分消耗資源的,并引入一系列不同于本地調用或遠程過程的異常。服務調用是不同于普通遠程過程調用的。
提供和消費服務需要盡可能的容易,所以應當避免隱藏過多服務之間所發生的交互。服務發送和接受的消息、服務的契約以及服務本身是SOA中首先需要確立的。這里面所包含的意思,對于任何建模的語言和工具來說,就是起碼應該對編寫服務的
程序員提供這幾個概念方面的API.總而言之,服務通過外部接口隱藏內部細節,暴露服務的功能;于服務的交互是一個顯式的行為,它依賴服務的提供者和消費者之間消息傳遞。
2)共享契約和Schema,而不是Class類
根據服務的描述(某種契約),服務的消費者和提供者應該擁有消費或提供服務所需要的所有東西。根據松耦合原則,服務的提供者不應該依賴消費者在它自己環境下所能提供的代碼重用能力;因為服務可能被用在不同的
開發時和運行時環境中。該原則在很大程度上限制了可以在SOA中交換的數據類型。理想的數據格式是使用可以被一個或多個Schema所驗證的XML文檔,因為幾乎所有可以想象到的語言環境都支持XML.
3)策略驅動
要跟一個服務交互,必須滿足兩組正交的
需求:
1)服務提供者的功能、語法和語義必須滿足服務消費者的需求,
2)技術能力和技術需求必須相符。
打個比方,一個服務提供者可以很好地滿足一個服務消費者的要求,但是它是通過JMS來提供服務的,而消費者卻只能使用HTTP(例如它是在.NET平臺上實現的);提供者可能要求通過XML加密標準在消息層進行加密,而消費者只支持SSL的傳輸層加密。即便在那些雙方都具備所需要的能力的情況下,這些能力也需要被“激活”--例如,服務提供者可能會有必要根據不同的消費者對應答消息采用不同的加密算法。
為了支持各式各樣不同設備和不同能力的服務消費者來訪問服務,SOA工具集必須引入某種策略機制。服務的功能性特征是由它們的接口來描述,而這些非功能
性能力和需求則是用策略文件來指定的。
4)自治
跟“清晰的邊界”相關的一條準則是,一個服務應該是自治的,即,它跟外界的唯一關系(至少從SOA的角度來看)是通過它的接口。在某些情況下,一個服務還必須能夠切換它的運行期環境,例如,從輕量級的原型實現切換到完善的基于應用
服務器的互相協作的多個組件的實現,而不需要用戶做任何相應的改動。服務可以相互獨立地進行改變、部署和版本管理。服務的提供者應該能夠不依賴用戶能力而迅速切換服務到更新的版本;而一些用戶也無法或不愿意切換到新的服務接口(特別是那些服務提供者無法控制的用戶)。
5)用格式連接,而不是用程序API
服務都支持使用特定的連接格式。這條原則和“清晰的邊界”原則關系非常大,不過是引入了一個新的角度:盡最大可能讓服務可以被訪問(從而達到長期的可用性),即,只要遵循服務所定義的交互策略,應該可以從任何平臺上通過符合服務接口定義的消息的交互來訪問一個服務。比如,要
測試某個服務是否符合這個準則,可以看看是否能使用某種非主流的動態編程語言,例如Perl,Python或
Ruby來調用或提供這項服務。雖然這些語言在當下的技術藍圖中無足輕重,但可以作為試紙來評估服務是否滿足下列約束:
1)所有消息的格式使用公開標準,或人類可讀的描述;
2)不需要耗費很多工作就可以創建符合特定Schema的消息,也不需要依賴特定的程序庫;
3)正確通訊所需的額外信息(例如為了
安全或
可靠性所創建的頭部信息)的語義和語法應該依照公開規范或標準;
4)與服務交互相關的傳輸(或傳送)協議中至少有一個是標準的
網絡協議(或可以通過標準網絡協議進行訪問的);
6)面向文檔
在服務交互的時候,數據是通過文檔傳遞的。文檔是顯式建模的樹狀容器。在上面提到過的自描述性是面向文檔的一個重要特征。理想狀況下的文檔應該是按照真實世界的文檔來建模的,如采購單、發票或帳戶聲明。設計良好的文檔在特定問題域的上下文環境中很有幫助,即它應該被一個或多個服務所采用。
類似于真實世界的紙質文檔,在服務中交換的文檔會包含冗余的信息。例如,客戶的地址可能與客戶的ID信息放在一起(盡管只有客戶ID就足夠了)。這些冗余的信息會被顯式的使用,它的作用在于將服務和服務消費者和服務提供者的底層數據模型進行隔離。當使用面向文檔模式的時候,服務調用成為了有意義的業務信息交換而不僅僅是上下文無關的RPC調用。盡管沒有要求,一般都假定用XML來作為這種文檔的格式/語法。
消息在通過SOA互連的異構系統間的參與者之間流動著。松耦合原則要求對于共有認知的依賴越小越好。當消息在分布式對象或RPC環境中傳遞時,客戶端和服務端依賴的是一組用同一個接口描述文檔自動生成的代理類(stubs和skeletons)。如果不采用這樣的方式,若契約本身不支持雙方交互則將無法通訊。所以說,RPC形式的架構必然要求客戶端和服務端代碼同步變化。
通過下面的比較我們來看一看??紤]以下消息:
“2006-03-1347113”
將它和
<order />
<date />2006-03-13</date />
<product />4711</product />
<qu
antity />3</quantity />
</order />
比較一下。
顯然后者比前者的可讀性更好,并且對于后者來說,除了使用固定的語法,參與者還可以使
用例如
XPath這樣的技術來隔離細微的非顛覆性的變化。反過來說,如果用了像XML這樣的自描述格式的消息卻仍然使用RPC方式進行通訊,其作用無非只能證明XML是最消耗帶寬的一種方式。如果你使用XML,那么一定要利用它的優點而不是缺點。
7)松耦合
大多數SOA倡導者都認同松耦合是一個重要的概念。但不幸的是,對于一個系統“松耦合”特性的認定卻有很多不同的選項。認定一個系統是松耦合還是緊耦合的,根據具體的需求和上下文可以有許多維度,從某些維度來看可能是松耦合,但是從另一些維度來看又可能那是緊耦合。這些維度包括:
時間:當(服務)參與者在時間維度上松耦合時,他們不是必須同時在線才能進行交互。這要求他們之間必須有某種緩沖和隊列的機制。當一個參與者發送消息到對方的時候,它不必依賴立即的消息回復也能繼續流程。
位置:如果參與者需要知道其它參與者的位置信息來進行通訊,那么位置的松耦合意味著當這些位置信息的改變時應該不需要重新編程、重新配置或重新啟動通訊中的各個參與者。這就隱含要求了服務的調用需要有一個尋址過程,并需要某種目錄或地址簿存儲服務終端的位置。
類型:類似編程語言中的靜態類型/動態類型或強類型/弱類型,類型的松耦合使得服務的參與者不依賴文檔的全部或哪怕部分結構。
版本:服務的參與者可能依賴特定版本的服務接口,也可能可以接口接口的(一定程度上)變化。越是依賴服務的特定版本,參與者的松耦合的程度就越低(在該維度上)。一個不錯的參考準則是Postel法則:服務提供者的實現應當盡可能接受各種版本,以擁有更大的自由度(甚至可以容錯),而服務的消費者則應該盡可能地遵循特定的語法和文檔接口。這樣可以增加系統整體上的可靠性和靈活性。
關聯:在某些情況下,服務消費者和服務提供者之間是1:1的關系,尤其是在“請求-答復”式交互或使用顯式的消息隊列的情況下。而在另外一些情況中,服務的消費者(叫“消息發送者”或“事件源”更合適)可能不知道甚至根本不在乎收到的消息數。
查詢:請求服務調用的參與者既可以根據服務提供者的(物理的或邏輯的)名字來跟它們通訊,也可以首先根據一組能力描述執行一個服務查找操作。這意味著需要有一個可以將消費者需求和服務提供者能力進行匹配的服務注冊表或服務倉庫。
接口:既可以要求參與者依賴服務所提供的特定接口,也可以要求它們支持一個通用的接口。如果使用通用接口,所有使用這個通用接口的參與者就可以和所有提供這個通用接口的參與者進行交互。盡管乍一看這樣做非常別扭,但這種單一(統一)通用接口卻是WWW結構中的核心所在。
任何創建的系統不可能、也不需要滿足上述所有維度的松耦合。對于不同類型的服務需要做不同程度的權衡。
8)兼容工業標準
在準備實施SOA的時候一條關鍵的原則就是依賴標準而不是依賴特定的API。從技術層面上來說,標準包括數據格式、元信息、傳輸協議、以及業務級別的文檔格式(如UBL)。
9)廠商無關
在任何架構準則中,都不應該依賴某個特定廠商的產品。在將抽象概念轉化到實際可運行的系統的過程中,不可避免地要選用某個特定的產品,不論是商業的或
開源的軟件。但是不應該在架構一級上就先入為主地考慮到這些決定。這就是說要盡量考慮到標準的互可操作性和可移植性。這樣一來,參與者可以使用支持標準的任何技術來構建,而不用受制于廠商的產品路線。
10)元數據驅動在整個SOA架構中,所有的元信息必須以恰當的方式存儲在某個地方,使得它們可以同時在設計時和運行時被發現、獲取和解釋。這些元信息包括服務接口的描述、參與者、服務終端(endpoint)、綁定信息(bingdings)、組織的結構和職責、文檔類型和schema、消費者-提供者關系,等等。這些元信息的使用應該利用代碼生成或解釋的方式盡可能地自動化,并成為服務和參與者生命周期中的一部分。
原文轉自:http://www.kjueaiud.com