天天看點

微觀SOA:服務設計原則及其實踐方式(上篇)

       大量網際網路公司都在擁抱SOA和服務化,但業界對SOA的很多讨論都比較偏向高大上。本文試圖從稍微不同的角度,以相對接地氣的方式來讨論SOA,集中讨論SOA在微觀實踐層面中的緣起、本質和具體操作方式,另外也用相當篇幅介紹了當今網際網路行業中各種流行的遠端調用技術等等,比較适合從事實際工作的架構師和程式員來閱讀。

  為了友善閱讀,本話題将分為兩篇展現。本文是上篇,着眼于微觀SOA的定義,并簡單分析其核心原則。

  亞馬遜CEO傑夫·貝佐斯:鮮為人知的SOA大師

  由于SOA有相當的難度和門檻,不妨先從一個小故事說起,從中可以管窺一點SOA的大意和作用。

  按照亞馬遜前著名員工Steve Yegge著名的“酒後吐槽”,2002年左右,CEO貝佐斯就在亞馬遜強制推行了以下六個原則(摘自酷殼):

  1. 所有團隊的程式子產品都要以通過Service Interface 方式将其資料與功能開放出來。
  2. 團隊間的程式子產品的資訊通信,都要通過這些接口。
  3. 除此之外沒有其它的通信方式。其他形式一概不允許:不能使用直接鍊結程式、不能直接讀取其 他團隊的資料庫、不能使用共享記憶體模式、不能使用别人子產品的後門、等等,等等,唯一允許的 通信方式隻能是能過調用 Service Interface。
  4. 任何技術都可以使用。比如:HTTP、Corba、Pubsub、自定義的網絡協定、等等,都可以,貝 佐斯不管這些。
  5. 所有的Service Interface,毫無例外,都必須從骨子裡到表面上設計成能對外界開放的。也就是 說,團隊必須做好規劃與設計,以便未來把接口開放給全世界的程式員,沒有任何例外。
  6. 不這樣的做的人會被炒鱿魚。

  據說,亞馬遜網站展示一個産品明細的頁面,可能要調用200-300個Service,以便生成高度個性化的内容。

  Steve還提到:

Amazon已經把文化轉變成了“一切以Service第一”為系統架構的公司,今天,這已經成為他們進行所有設計時的基礎,包括那些絕不會被外界所知的僅在内部使用的功能。

那時,如果沒有被解雇的的恐懼他們一定不會去做。我是說,他們今天仍然怕被解雇,因為這基本上是那兒每天的生活,為那恐怖的海盜頭子貝佐斯工作。不過,他們這麼做的确是因為他們已經相信Service這就是正确的方向。他們對于SOA的優點和缺點沒有疑問,某些缺點還很大,也不疑問。但總的來說,這是正确的,因為,SOA驅動出來的設計會産生出平台(Platform)。

  今天,我們都知道亞馬遜從世界上最大圖書賣場進化為了世界上最成功的雲平台……

  貝佐斯的六原則展示出高度的遠見和超強的信念,即使放到十幾年後的今天,依然覺得振聾發聩……想起一句老話:“不謀萬世者,不足以謀一時;不謀全局者,不足以謀一隅。”

  當然,像貝佐斯這種将神性與魔性集于一身的專橫人物,既可能創造劃時代的進步,也可能制造前所未有的災難。

  SOA漫談:宏觀與微觀

  SOA即面向服務架構,是一個特别大的話題。

  為了友善讨論,我在此先草率的将SOA分為兩個層面(大概模仿宏觀和微觀經濟學,但這裡的劃分沒有絕對界限):

宏觀SOA:面向高層次的部門級别、公司級别甚至行業級别;涉及商業、管理、技術等方面的綜合的、全局的考慮;架構體系上包括服務治理(governance,如服務注冊,服務監控),服務編排(orchestration,如BPM,ESB),服務協同(choreography,更多面向跨企業內建)等等。我認為SOA本身最主要是面向宏觀層面的架構,其帶來益處也最能在宏觀高層次上展現出來,同時大部分SOA的業界讨論也集中在這方面。

微觀SOA:面向有限的、局部的團隊和個人;涉及獨立的、具體的服務在業務、架構、開發上的考慮。

  很多業界專家都認為SOA概念過于抽象,不接地氣,我認為主要是宏觀SOA涉及面太廣,經常需要做通盤考慮,而其中很多方面距離一般人又比較遠。而在微觀層面的SOA更容易達到過去提出的“三貼近”:貼近實際、貼近生活、貼近群衆。

  同時,宏觀SOA要取得成功,通常的前提也是SOA在微觀層面的落地與落實,正如宏觀經濟學一般要有堅實的微觀基礎(比如大名鼎鼎的凱恩斯主義曾廣受诟病的一點就是缺乏微觀基礎)

  是以,我們着眼于SOA落地的目的,着重來分析微觀SOA,也算是對業界主流探讨的一個小小的補充。

  SOA定義

  按照英文維基百科定義:SOA是一種“軟體”和“軟體架構”的設計模式(或者叫設計原則)。它是基于互相獨立的軟體片段要将自身的功能通過“服務”提供給其他應用。

  什麼是“服務”?按照OASIS的定義:Service是一種按照既定“接口“來通路一個或多個軟體功能的機制(另外這種通路要符合“服務描述”中政策和限制)

  Service示例(代碼通常以java示例)

public interface Echo {
    String echo(String text);
}
public class EchoImpl implements Echo {
    public String echo(String text) {
        return text;
    }
}
           

  可能每個開發人員每天都在寫類似的面向對象的Service,難道這就是在實施SOA嗎?

  SOA設計原則

  既然SOA是設計原則(模式),那麼它包含哪些内容呢?事實上,這方面并沒有最标準的答案,多數是遵從著名SOA專家Thomas Erl的歸納:

标準化的服務契約 Standardized service contract 服務的松耦合 Service loose coupling 服務的抽象 Service abstraction 服務的可重用性 Service reusability 服務的自治性 Service autonomy 服務的無狀态性 Service statelessness 服務的可發現性 Service discoverability 服務的可組合性 Service composability ....

  這些原則總的來說要達到的目的是:提高軟體的重用性,減少開發和維護的成本,最終增加一個公司業務的靈活度。

  但是,業界著名專家如Don Box,David Orchard等人對SOA又有各自不同的總結和側重。

  SOA不但沒有絕對統一的原則,而且很多原則本身的内容也具備相當模糊性和寬泛性:例如,所謂松耦合原則需要松散到什麼程度才算是符合标準的呢?這就好比一個人要帥到什麼程度才算是帥哥呢?一棟樓要高到多少米才算是高樓呢?可能不同人心中都有自己的一杆秤……部分由于這些理論上的不确定因素,不同的人了解或者實施的SOA事實上也可能有比較大的差别。

  淺析松耦合原則

  SOA原則比較多,真正的了解往往需要逐漸的積累和體會,是以在此不詳細展開。這裡僅以服務的松耦合為例,從不同次元來簡單剖析一下這個原則,以說明SOA原則内涵的豐富性:

實作的松耦合:這是最基本的松耦合,即服務消費端不需要依賴服務契約的某個特定實作,這樣服務提供端的内部變更就不會影響到消費端,而且消費端未來還可以自由切換到該契約的其他提供方。

時間的松耦合:典型就是異步消息隊列系統,由于有中介者(broker),是以生産者和消費者不必在同一時間都保持可用性以及相同的吞吐量,而且生産者也不需要馬上等到回複。

位置的松耦合:典型就是服務注冊中心和企業服務總線(ESB),消費端完全不需要直接知道提供端的具體位置,而都通過注冊中心來查找或者服務總線來路由。

版本的松耦合:消費端不需要依賴服務契約的某個特定版本來工作,這就要求服務的契約在更新時要盡可能的提供向下相容性。

  SOA與傳統軟體設計

  我們可以認為:SOA ≈ 子產品化開發 + 分布式計算

  将兩者傳統上的最佳實踐結合在一起,基本上可以推導出SOA的多數設計原則。SOA從軟體設計(暫不考慮業務架構之類)上來講,自身的新東西其實不算很多。

  SOA原則的應用

  基于SOA的原則,也許我們很難說什麼應用是絕對符合SOA的,但是卻能剔除明顯不符合SOA的應用。

  用上述标準化契約,松耦合和可重用這幾個原則來嘗試分析一下上面Echo示例:

Echo的服務契約是用Java接口定義,而不是一種與平台和語言無關的标準化協定,如WSDL,CORBA IDL。當然可以擡杠,Java也是行業标準,甚至全國牙防組一緻認定的東西也是行業标準。

Java接口大大加重了與Service用戶端的耦合度,即要求用戶端必須也是Java,或者JVM上的動态語言(如Groovy、Jython)等等……

同時,Echo是一個Java的本地接口,就要求調用者最好在同一個JVM程序之内……

Echo的業務邏輯雖然簡單獨立,但以上技術方面的局限就導緻它無法以後在其他場合被輕易重用,比如分布式環境,異構平台等等。

  是以,我們可以認為Echo并不太符合SOA的基本設計原則。

  透明化的轉向SOA?

  修改一下上面的Echo,添加Java EE的@WebServices注解(annotation)

@WebServices
public class EchoImpl implements Echo {
    public String echo(String text) {
        return text;
    }
}
           

  現在将Echo釋出為Java WebServices,并由底層架構自動生成WSDL來作為标準化的服務契約,這樣就能與遠端的各種語言和平台互操作了,較好的解決了上面提到的松耦合和可重用的問題。按照一般的了解,Echo似乎就成為比較理想的SOA service了。

  但是……即使這個極端簡化的例子,也會引出不少很關鍵的問題,它們決定SOA設計開發的某些難度:

将一個普通的Java對象通過添加注解“透明的”變成WebServices就完成了從面向對象到面向服務的跨越?

通過Java接口生成WSDL服務契約是好的方式嗎?

WebServices是最合适遠端通路技術嗎?

  面向對象和面向服務的對比

  面向對象(OO)和面向服務(SO)在基礎理念上有大量共通之處,比如都盡可能追求抽象、封裝和低耦合。

  但SO相對于OO,又有非常不同的典型應用場景,比如:

多數OO接口(interface)都隻被有限的人使用(比如團隊和部門内),而SO接口(或者叫契約)一般來說都不應該對使用者的範圍作出太多的限定和假設(可以是不同部門,不同企業,不同國家)。還記得貝佐斯原則嗎?“團隊必須做好規劃與設計,以便未來把接口開放給全世界的程式員,沒有任何例外”。

多數OO接口都隻在程序内被通路,而SO接口通常都是被遠端調用。

  簡單講,就是SO接口使用範圍比一般OO接口可能廣泛得多。我們用網站打個比方:一個大型網站的web界面就是它整個系統入口點和邊界,可能要面對全世界的通路者(是以經常會做國際化之類的工作),而系統内部傳統的OO接口和程式則被隐藏在web界面之後,隻被内部較小範圍使用。而理想的SO接口和web界面一樣,也是變成系統入口和邊界,可能要對全世界開發者開放,是以SO在設計開發之中與OO相比其實會有很多不同。

  小結

  在前述比較抽象的SOA大原則的基礎上,我們可嘗試推導一些較細化和可操作的原則,在具體實踐中展現SO的獨特之處。

原文連結http://www.infoq.com/cn/articles/micro-soa-1