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

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

為了方便閱讀,本話題將分為兩篇展現。本文是上篇,著眼於微觀SOA的定義,並簡單分析其核心原則。

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

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

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

  • 所有團隊的程式模組都要以通過Service Interface 方式將其資料與功能開放出來。
  • 團隊間的程式模組的資訊通訊,都要通過這些介面。
  • 除此之外沒有其它的通訊方式。其他形式一概不允許:不能使用直接鏈結程式、不能直接讀取其他團隊的資料庫、不能使用共享記憶體模式、不能使用別人模組的後門、等等,等等,唯一允許的通訊方式只能是能過呼叫 Service Interface。
  • 任何技術都可以使用。比如:HTTP、Corba、Pubsub、自定義的網路協議、等等,都可以,貝佐斯不管這些。
  • 所有的Service Interface,毫無例外,都必須從骨子裡到表面上設計成能對外界開放的。也就是說,團隊必須做好規劃與設計,以便未來把介面開放給全世界的程式設計師,沒有任何例外
  • 不這樣的做的人會被炒魷魚

據說,亞馬遜網站展示一個產品明細的頁面,可能要呼叫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的獨特之處。請關注本系列文章的下篇!
來自:infoQ
相關閱讀
評論(2)

相關文章