架構(gòu)風(fēng)格,就像藝術(shù)運動一樣,必須在其發(fā)展的時代背景下加以理解,而這種架構(gòu)比其他任何架構(gòu)風(fēng)格都更能體現(xiàn)這一規(guī)律。
經(jīng)常影響架構(gòu)決策的外部力量的組合,再加上一個符合常理的但最終是災(zāi)難性的組織哲學(xué),注定了這個架構(gòu)是無關(guān)緊要的。然而,它提供了一個很好的例子,說明了一個特定的組織理念是如何合乎邏輯的,但卻阻礙了開發(fā)過程中最重要的部分。
歷史與哲學(xué)
這種面向服務(wù)的架構(gòu)在20世紀(jì)90年代末當(dāng)公司逐漸成為企業(yè)時出現(xiàn):與較小的公司合并,以極快的速度增長,并需要更復(fù)雜的IT來適應(yīng)這種增長。然而,計算資源是稀缺的、珍貴的、商業(yè)化的。分布式計算剛好成為可能和必要的,許多公司需要可變的可擴展性和其他有益的特性。
許多外部驅(qū)動因素迫使這個時代的架構(gòu)師傾向于具有重要約束的分布式架構(gòu)。在開源操作系統(tǒng)被認(rèn)為足夠可靠來完成重要的工作之前,操作系統(tǒng)非常昂貴,而且每臺機器都要獲取許可證。類似地,商業(yè)數(shù)據(jù)庫服務(wù)器帶有拜占庭式的許可計劃,這導(dǎo)致應(yīng)用服務(wù)器供應(yīng)商(提供數(shù)據(jù)庫連接池)與數(shù)據(jù)庫供應(yīng)商展開競爭。因此,架構(gòu)師被期望盡可能多地重用。事實上,所有形式的重用都成為了這個架構(gòu)中的主導(dǎo)思想,我們會在“重用…和耦合”中討論它的副作用。
這種架構(gòu)風(fēng)格也說明了架構(gòu)師可以在多大程度上推動技術(shù)分區(qū)的思想,技術(shù)分區(qū)的動機是好的,但結(jié)果卻很糟糕。
拓?fù)浣Y(jié)構(gòu)
這種面向服務(wù)架構(gòu)的拓?fù)浣Y(jié)構(gòu)如圖16-1所示。

并不是所有這種風(fēng)格的架構(gòu)的例子都有圖16-1所示的確切的層次,但它們都遵循相同的理念,即在架構(gòu)中建立服務(wù)分類,每一層都有特定的職責(zé)。
面向服務(wù)的架構(gòu)是一種分布式體系結(jié)構(gòu);圖16-1中沒有顯示精確的邊界劃分,因為它會隨著組織的不同而變化。
分類
架構(gòu)師在這個架構(gòu)中的驅(qū)動哲學(xué)是以企業(yè)級重用為中心。許多大公司對他們必須不斷地重寫軟件感到惱火,于是他們想出了一個逐步解決這個問題的策略。
業(yè)務(wù)服務(wù)
業(yè)務(wù)服務(wù)位于此架構(gòu)的頂部,并提供入口點。例如,ExecuteTrade或PlaceOrder之類的服務(wù)表示領(lǐng)域行為。一個常見的試金石測試-對于這些每一個服務(wù),架構(gòu)師能否肯定地回答“我們是否從事…”這一問題?
這些服務(wù)定義不包含代碼,只包含輸入、輸出,有時還包含模式信息。它們通常由業(yè)務(wù)用戶定義,因此稱為業(yè)務(wù)服務(wù)。
企業(yè)服務(wù)
企業(yè)服務(wù)包含細(xì)粒度的共享實現(xiàn)。通常,開發(fā)團隊的任務(wù)是圍繞特定業(yè)務(wù)領(lǐng)域構(gòu)建原子行為:CreateCustomer、CalculateQuote等等。這些服務(wù)是組成粗粒度業(yè)務(wù)服務(wù)的構(gòu)建塊,通過編制引擎連接在一起。在這種架構(gòu)中,職責(zé)分離是為了實現(xiàn)重用。如果開發(fā)人員能夠以剛好的粒度級別構(gòu)建細(xì)粒度的企業(yè)服務(wù),那么企業(yè)就不必再次重寫這一部分的業(yè)務(wù)工作流。逐漸地,業(yè)務(wù)將以可重用企業(yè)服務(wù)的形式建立可重用資產(chǎn)的集合。
不幸的是,現(xiàn)實的動態(tài)性挑戰(zhàn)了這些嘗試。業(yè)務(wù)組件不像建筑材料一樣,一個解決方案可以持續(xù)幾十年。市場、技術(shù)變化、工程實踐和一系列其他因素證明了試圖將穩(wěn)定性強加于軟件世界的努力是行不通的。
應(yīng)用服務(wù)
并非架構(gòu)中的所有服務(wù)都需要與企業(yè)服務(wù)相同級別的粒度或重用。應(yīng)用程序服務(wù)是一次性的、單一的實現(xiàn)服務(wù)。例如,可能有一個應(yīng)用程序需要獲取地理位置的功能,但組織不想花時間或精力使其成為可重用的服務(wù)。通常由單個應(yīng)用團隊擁有的應(yīng)用服務(wù)解決了這些問題。
基礎(chǔ)設(shè)施服務(wù)
基礎(chǔ)設(shè)施服務(wù)提供運營相關(guān)的能力,例如監(jiān)控、日志記錄、身份驗證和授權(quán)。這些服務(wù)往往是具體的實現(xiàn),由與運營部門密切合作的共享基礎(chǔ)設(shè)施團隊擁有。
編制引擎
編制引擎構(gòu)成了這個分布式體系結(jié)構(gòu)的核心,它使用編制(包括事務(wù)協(xié)調(diào)和消息轉(zhuǎn)換等功能)將業(yè)務(wù)服務(wù)實現(xiàn)縫合在一起。這種架構(gòu)通常與一個或幾個關(guān)系數(shù)據(jù)庫綁定,而不是像微服務(wù)架構(gòu)那樣為每個服務(wù)綁定一個數(shù)據(jù)庫。因此,事務(wù)行為在編制引擎中以聲明方式處理,而不是在數(shù)據(jù)庫中。
編制引擎定義業(yè)務(wù)和企業(yè)服務(wù)之間的關(guān)系,它們?nèi)绾斡成涞揭黄?,以及事?wù)邊界在哪里。它還充當(dāng)一個集成中心,允許架構(gòu)師將定制代碼包和遺留軟件系統(tǒng)集成在一起。因為這種機制形成了架構(gòu)的核心,康威定律正確地預(yù)測,負(fù)責(zé)這個引擎的集成架構(gòu)師團隊將成為組織內(nèi)的政治力量,最終成為官僚主義瓶頸。
雖然這種方式聽起來可能很有吸引力,但實際上它更多是一場災(zāi)難。
將事務(wù)行為轉(zhuǎn)移到編制工具上聽起來不錯,但找到事務(wù)的正確粒度級別變得越來越困難。雖然可以在分布式事務(wù)中構(gòu)建一些服務(wù),但由于開發(fā)人員必須確定服務(wù)之間的適當(dāng)事務(wù)邊界在哪里,所以架構(gòu)將會變得越來越復(fù)雜。
消息流
所有請求都通過編制引擎,它是這種架構(gòu)中邏輯所在的位置。因此,即使對于內(nèi)部調(diào)用,消息流也會通過引擎,如圖16-2所示。

在圖16-2中,CreateQuote業(yè)務(wù)級服務(wù)調(diào)用服務(wù)總線,服務(wù)總線定義了由對CreateCustomer和CalculateQuote的調(diào)用組成的工作流,每個調(diào)用還具有對應(yīng)用服務(wù)的調(diào)用。服務(wù)總線充當(dāng)此架構(gòu)中所有調(diào)用的中介,同時充當(dāng)集成中心和編制引擎。
重用…和耦合
這種架構(gòu)的一個主要目標(biāo)是在服務(wù)級別重用 - 逐步構(gòu)建業(yè)務(wù)行為的能力,隨著時間的推移,業(yè)務(wù)行為可以逐漸地重用。這個架構(gòu)中的架構(gòu)師被指示盡可能積極地尋找重用機會。例如,考慮圖16-3所示的情況。

在圖16-3中,架構(gòu)師意識到保險公司中的每個部門都包含客戶的概念。因此,面向服務(wù)架構(gòu)的正確策略需要將客戶部分提取到可重用的服務(wù)中,并允許原始服務(wù)引用規(guī)范的客戶服務(wù),如圖16-4所示。

在圖16-4中,架構(gòu)師將所有客戶行為隔離到一個單獨的客戶服務(wù)中,實現(xiàn)了明顯的重用目標(biāo)。
然而,架構(gòu)師只是慢慢地意識到這種設(shè)計的負(fù)面權(quán)衡結(jié)果。首先,當(dāng)一個團隊主要圍繞重用構(gòu)建一個系統(tǒng)時,他們也會在組件之間產(chǎn)生大量耦合。例如,在圖16-4中,對客戶服務(wù)的更改會波及到所有其他服務(wù),這使得變更具有風(fēng)險。因此,在面向服務(wù)的架構(gòu)中,架構(gòu)師吃力地進行增量變更—每次變更都可能產(chǎn)生巨大的連鎖反應(yīng)。這反過來導(dǎo)致了協(xié)調(diào)部署、整體測試,以及其他拉動工程效率的因素的需要。
將行為整合到一個地方的另一個負(fù)面影響是:考慮圖16-4中的汽車和傷殘保險。為了支持單一的客戶服務(wù),它必須包括組織所知道的關(guān)于客戶的所有細(xì)節(jié)。汽車保險需要駕照,駕照是人的財產(chǎn),而不是車輛。因此,客戶服務(wù)必須包括傷殘保險部門不關(guān)心的駕照的細(xì)節(jié)。然而,處理傷殘問題的團隊必須處理單個客戶定義的額外復(fù)雜性。也許這種架構(gòu)最具破壞性的啟示來自于這樣一種現(xiàn)實:構(gòu)建一個如此專注于技術(shù)劃分的架構(gòu)是不切實際的。雖然從分離和重用哲學(xué)的角度來看這是有意義的,但實際上它卻是一場噩夢。像CatalogCheckout這樣的領(lǐng)域概念在整個架構(gòu)中傳播得如此之少,以至于它們實際上都被碾得粉碎。開發(fā)人員通常處理諸如“向CatalogCheckout添加新地址行”之類的任務(wù)。在面向服務(wù)的架構(gòu)中,這可能涉及在幾個不同的層中的幾十個服務(wù),加上對單個數(shù)據(jù)庫模式的更改。而且,如果當(dāng)前的企業(yè)服務(wù)沒有在正確的事務(wù)粒度上定義,開發(fā)人員將不得不更改其設(shè)計或構(gòu)建一個新的、幾乎相同的服務(wù)來改變事務(wù)行為。關(guān)于重用到此為止。
架構(gòu)特性評級
我們現(xiàn)在用來評估架構(gòu)的許多現(xiàn)代標(biāo)準(zhǔn)在這種架構(gòu)流行的時候并不是優(yōu)先考慮的。事實上,敏捷軟件運動剛剛開始的時候并沒有滲透到可能使用這種架構(gòu)的規(guī)模類型的組織當(dāng)中。
特性評級表中的一星級評級(如圖16-5所示)意味著特定的架構(gòu)特性在某種架構(gòu)中沒有得到很好的支持,而五星評級意味著架構(gòu)特性是某種架構(gòu)風(fēng)格中最強大的特性之一。記分卡中確定的每個特性的定義見第4章。
面向服務(wù)的架構(gòu)可能是有史以來最偏向技術(shù)分區(qū)的多功能架構(gòu)!事實上,對這種結(jié)構(gòu)缺點的抵制導(dǎo)致了更現(xiàn)代的架構(gòu),如微服務(wù)。盡管它是一個分布式架構(gòu),但它只有一個單一的量子,原因有兩個。首先,它通常使用單個數(shù)據(jù)庫或幾個數(shù)據(jù)庫,在架構(gòu)中創(chuàng)建跨多個不同關(guān)注點的耦合點。第二,也是更重要的是,編制引擎充當(dāng)一個巨大的耦合點,架構(gòu)的任何部分都不能具有與協(xié)調(diào)所有行為的中介器具有不同的架構(gòu)特性。因此,這種架構(gòu)設(shè)法找到單體和分布式架構(gòu)的缺點。

在這個架構(gòu)中,諸如可部署性和可測試性等現(xiàn)代工程目標(biāo)的得分是災(zāi)難性的,這兩個原因都是因為這些目標(biāo)得不到很好的支持,而且在那個時代,這些目標(biāo)并不重要(甚至不是渴望得到的)。
盡管在實現(xiàn)這些行為方面存在困難,但這種架構(gòu)確實支持一些目標(biāo),如彈性和可擴展性,因為工具供應(yīng)商通過跨應(yīng)用服務(wù)器和其他技術(shù)構(gòu)建會話復(fù)制,傾注了大量精力使這些系統(tǒng)具有可擴展性。但是,作為一個分布式架構(gòu),性能從來都不是這種架構(gòu)風(fēng)格的亮點,甚至是非常差的,因為每個業(yè)務(wù)請求都被分割到了橫跨架構(gòu)中很多部分
由于所有這些因素,簡單性和成本成了大多數(shù)架構(gòu)師傾向的反比關(guān)系。這個架構(gòu)是一個重要的里程碑,因為它教會了架構(gòu)師分布式事務(wù)在現(xiàn)實世界中有多困難以及技術(shù)分區(qū)的實際限制。