作者 Stefan Tilkov譯者 戴強斌 發(fā)布于 2007年4月10日 上午4時27分
在與許多客戶的接觸中,我發(fā)現(xiàn)有必要建立一套SOA的基本原則。下面的部分將介紹SOA中應有的基本原則。這些并非絕對真理,它們更像一個用于SOA相關(guān)討論的參考框架。你會發(fā)現(xiàn):前四項衍生自Don Box提出的四項原則,盡管隨著時間的流逝,這四項原則的描述可能已經(jīng)有了些變化。
服務被調(diào)用時,與實現(xiàn)其功能相關(guān)的內(nèi)容都應被傳遞過來。對服務的所有訪問都應該通過公共接口進行。調(diào)用服務時,非隱含的假設(shè)是必須的。“服務與消息緊密聯(lián)系,因為參數(shù)進出服務的唯一方式是通過消息進行的”。作為通用的模式,服務調(diào)用不應依賴于共享的上下文,而應被作為無狀態(tài)的模塊。契約描述了服務的功能性與非功能性的能力和特點,管理著服務提供的接口。服務調(diào)用是一個具有業(yè)務邏輯效果的行為,可能有大量的資源開銷,并且導致一系列不同于本地方法調(diào)用和遠程過程調(diào)用的錯誤。服務的調(diào)用絕非遠程過程調(diào)用。
服務的使用和提供應該盡可能地簡單,因此與服務間的交互沒必要被隱藏得太多。在SOA中,服務發(fā)送和接收的消息、服務契約以及服務本身都應當是最好的構(gòu)件。這就意味著,例如,被用到的編程模型和工具至少應該提供一個API,這個API會幫助服務的編程人員了解上述概念。總的來說,一個明確的接口會封裝服務的內(nèi)在實現(xiàn),而服務通過該接口發(fā)布自己的功能;與服務交互是一個具體的行為,它依賴于服務使用者和提供者之間消息的傳遞。
基于一份服務描述(一份契約),服務使用者和服務提供者都可以獲得使用或提供服務的全部所需。根據(jù)松耦合原則,服務提供者不能依靠服務使用者來重用那些依賴于使用者環(huán)境的代碼。畢竟,服務使用者可能使用不同的開發(fā)環(huán)境和運行環(huán)境。這條原則給SOA體系中所能交換的數(shù)據(jù)加上了嚴格的限制。理想的情況是,數(shù)據(jù)以符合一種或多種模式的XML文檔形式被交換,因為這種方式可應用于任何你能想到的編程環(huán)境。
因此,因為這條原則在基于DCOM和基于RMI的環(huán)境中是不可能被遵守的,所以這兩種環(huán)境基本上無法成為SOA的可用選項。
為了與服務交互,必須滿足以下兩組不同的要求:
例如,一個服務提供者提供了能夠精確滿足用戶需求的服務,但該服務是基于JMS的,可使用者只能使用HTTP方式(比如,服務被應用于.NET平臺)。服務提供者可能要求消息級別的加密采用XML加密標準,而使用者只支持采用SSL技術(shù)來保障傳輸層上的安全。即使在那些交互雙方都擁有足夠能力的案例中,它們的這些能力仍舊需要被“啟用”。例如,提供者可能根據(jù)不同的使用者需求,對響應的消息使用不同的算法進行加密。
為了使盡可能多的形形色色的使用者能對服務進行訪問,一種策略機制已經(jīng)被作為SOA工具集的一部分引入了。在服務接口對功能進行描述的同時,策略對不同的,非功能性的能力和需求進行了指定。(譯者注:策略指定的是服務之外的補充信息,是對服務使用者提出的特征要求)
與明確邊界原則相關(guān),服務自治意味著,接口成為服務與外界聯(lián)系的唯一方式,至少從SOA的角度來看是這樣的。需要注意的是,服務的運行環(huán)境一定是可變的。例如,在絲毫不影響使用者的情況下,就可以從輕量級的原型實現(xiàn)轉(zhuǎn)換到成熟的、基于應用服務器的協(xié)同組件集。服務能夠被彼此獨立的修改、部署、發(fā)布新版本和管理。服務提供者不能寄希望于服務使用者,期望它們依靠自己的能力迅速適應新版本的服務,有的使用者可能甚至沒這個能力或者根本不愿去適應新版本的服務接口(尤其是當這些服務接口超出了服務提供者控制范圍的時候)。
服務通常采用協(xié)議格式來發(fā)布,協(xié)議格式應該是明確的、可傳輸?shù)牟⑶冶环账С值?。這一點與前兩條原則非常相關(guān),但卻帶來了新的見解:為保證一個服務最大程度的可訪問性(及長期的可用性),只要交互過程遵守為該服務定義的策略,那么由任何依照服務接口進行消息交換的平臺都可以訪問該服務。例如,通過以這一原則來測試主流的動態(tài)編程語言(如Perl、Python或Ruby),我們可以去考慮該語言能否使用或提供一個特定的服務。雖然,在現(xiàn)有的技術(shù)實現(xiàn)里,這條原則可能還沒有發(fā)揮作用,但這個思路可以作為下列準則的試金石:
服務交互時,數(shù)據(jù)是以文檔的形式來傳遞的。文檔是一個被明確模塊化的,有層次結(jié)構(gòu)的數(shù)據(jù)容器。面向文檔的一個重要特征就是自描述。最理想的情況下,文檔是對現(xiàn)實世界中的文件(如訂單、發(fā)票或帳單)的建模。文檔應該被設(shè)計來確保它在問題域的上下文中發(fā)揮作用,這意味著它們可能應用于一個或更多的服務。
與現(xiàn)實世界的紙制文檔相似,和服務交換信息的文檔將包含冗余的信息。例如,文檔中可能同時包含了客戶ID和客戶地址信息(盡管客戶ID可能已經(jīng)足夠了)。這種冗余是可以接受的,因為它將服務使用者和提供者雙方的服務接口和隱含數(shù)據(jù)模型隔離開來。應用面向文檔的模式的同時,服務調(diào)用成為有意義的業(yè)務邏輯消息的交換,而非上下文無關(guān)的RPC調(diào)用。雖然通??梢哉J為XML將被作為服務文檔的格式和語法,但它還沒有成為標準。
在一個SOA連接中,參與者之間的消息流轉(zhuǎn)于不同的系統(tǒng),使得各個系統(tǒng)之間彼此獨立。松耦合原則要求參與者對共知的依賴越少越好。當消息在分布式對象或RPC基礎(chǔ)架構(gòu)中發(fā)送時,客戶端和服務器端使用由同一個接口描述文檔生成的代理類(stub和skeleton)。如果不是這種情況的話,當契約不支持雙方的交互時,通訊就會停止。因為這個原因,RPC風格的基礎(chǔ)架構(gòu)要求客戶端和服務器端程序代碼的同步運行。
下面將通過比較來說明這個問題。請仔細思考下面的消息:
2006-03-1347113
與之相比:
2006-03-13 4711
3
多數(shù)SOA的倡導者都認為松耦合是一個很重要的概念。不幸的是,對于究竟哪些特征造成一個系統(tǒng)松耦合,有許多不同的看法。一個系統(tǒng)可以在多個維度表現(xiàn)為松耦合或緊耦合,它依賴于具體的要求和上下文,系統(tǒng)可能會在一些維度是松耦合的,在另一些維度是緊耦合的。這些維度包括:
創(chuàng)造一個滿足以上所有維度的松耦合系統(tǒng),既不可行,也沒必要。不同類型的服務要做不同的取舍。Carlos Perez的經(jīng)典之作中(如這里和這里)有更多的關(guān)于松耦合各個維度的討論。
一個SOA應用中應遵循的一個關(guān)鍵原則是,信賴標準而非專有的API和格式。標準存在于技術(shù)方面,如數(shù)據(jù)格式、元數(shù)據(jù)、傳輸協(xié)議;也存在于業(yè)務層面,如文檔的類型。(例如,UBL中所提到的那些)(譯者注:UBL定義了業(yè)務文檔的通用XML庫,UBL的文檔類型包括訂單、發(fā)票等)
很顯然,一些人認為專有的解決方案,如一些EAI或消息服務提供商提供的方案,都遵循SOA原則。這個原則不遺余力地強調(diào)標準的重要性。當然,由于有太多可供選擇的標準,什么情況用何種標準成了頗具爭議的問題。標準的一個重要方面是它的可接受性(在Web服務的標準中,基本上可以認為“Microsoft肯定要插上一腳”)。
任何架構(gòu)性的原則都不應依賴特定供應商的產(chǎn)品。將抽象的概念轉(zhuǎn)化為具體的,可運行的系統(tǒng)的過程中,不可避免的要決定使用何種具體的產(chǎn)品,包括商業(yè)的或者免費開源的軟件。這些決定都不應影響架構(gòu)層。這就意味著要盡可能的依賴互操作性和可移植性的標準。因此,要應用支持適當標準的技術(shù)來構(gòu)建服務提供者和使用者,不要受限于任何軟件供應商的技術(shù)路線。
SOA中所有的元數(shù)據(jù)對象都需要被按照一種方式儲存起來,這種方式將確保元數(shù)據(jù)對象能夠在設(shè)計和運行時被發(fā)現(xiàn)、檢索和解釋。元數(shù)據(jù)對象包括對服務接口、參與者、端點和綁定信息、組織單元和職責、文檔類型或模式、使用者或提供者關(guān)系等的描述。這些對象的用途應當是被代碼自動生成或者解釋,成為服務和參與者生命周期的一部分。