單體架構(gòu),是指由一臺或多臺計算機組成中心節(jié)點。將數(shù)據(jù)集中存儲于這個中心節(jié)點中,并且整個系統(tǒng)的所有業(yè)務(wù)功能也均在此集中處理。也就是說,在這種架構(gòu)下,每個終端或客戶端機器僅僅負(fù)責(zé)數(shù)據(jù)的錄入和輸出,而數(shù)據(jù)的存儲與控制處理完全交由單體系統(tǒng)來完成。業(yè)務(wù)集中 業(yè)務(wù)集中,指的是所有業(yè)務(wù)都統(tǒng)一處理。這樣做的好處是,業(yè)務(wù)較較容易做到規(guī)范、也比較容易被監(jiān)管,進而控制風(fēng)險。在很多傳統(tǒng)金融企業(yè)中,這樣的架構(gòu)設(shè)計頗為常見。 計算集中 計算集中,指的是所有對數(shù)據(jù)的加工處理邏輯,都是集中完成的。當(dāng)然,這也是后來這種架構(gòu)方式,飽受爭議之處。隨著業(yè)務(wù)規(guī)模的增加,對計算能力要求突增,這種計算集中的方式較難做到擴展。 數(shù)據(jù)集中 數(shù)據(jù)集中,指的是所有相關(guān)數(shù)據(jù)都統(tǒng)一存儲,集中訪問。
研發(fā)成本高 因為是單體應(yīng)用,即使應(yīng)用間存在功能重疊,也很難實現(xiàn)共享。一般不存在業(yè)務(wù)系統(tǒng)間的互相調(diào)用,使用什么功能就本地開發(fā)完成,不依賴其他應(yīng)用。當(dāng)有頻繁的需求變更時,需要重新編碼、測試,完成開發(fā)全流程,很難做到快速迭代。因?qū)ΜF(xiàn)在的快速業(yè)務(wù)創(chuàng)新及敏捷交付的需求,很難滿足。 維護困難 這類系統(tǒng)一般是是通過鏈條狀的本地調(diào)用完成,往往是由一個人或團隊負(fù)責(zé)開發(fā)和維護。隨著業(yè)務(wù)的發(fā)展和需求變化,本地代碼在不斷的迭代和變更,最后形成了一個個垂直的功能孤島,只有原來的開發(fā)者才理解接口調(diào)用關(guān)系和功能需求,一旦原有的開發(fā)者離職或者調(diào)到其他項目組,這些功能模塊的運維就會變得非常困難。隨著業(yè)務(wù)的發(fā)展和功能膨脹,這種架構(gòu)很容易發(fā)生腐化現(xiàn)象。 單點故障 這類設(shè)計的可靠性差,存在單點故障風(fēng)險。如發(fā)生某個應(yīng)用BUG,可能會波及整個系統(tǒng)的使用,造成全局性的影響。 擴展性差 可伸縮性差:水平擴展只能基于整個系統(tǒng)進行擴展,無法針對某一個功能模塊按需擴展。 為了應(yīng)對傳統(tǒng)單體架構(gòu)的問題,一般會采用拆分的策略。其核心就是降低軟件的復(fù)雜性,減少開發(fā)工作量,從而降低開發(fā)成本,提高軟件生產(chǎn)率。'分而治之'的結(jié)論,把復(fù)雜的問題分解為很多容易解決的小問題,原來的問題也就容易解決。針對單體的拆分,可以遵從不同的邏輯及角度,
面向流程拆分:將整個業(yè)務(wù)流程拆分為幾個階段,每個階段作為一部分。
面向服務(wù)拆分:將系統(tǒng)提供的服務(wù)拆分,每個服務(wù)作為一部分。
面向功能拆分:將系統(tǒng)提供的功能拆分,每個功能作為一部分。 理解這三種思路的關(guān)鍵就在于如何理解'流程'、'服務(wù)'、'功能'三者的聯(lián)系和區(qū)別。從范圍上來看,從大到小依次為:流程 > 服務(wù) > 功能。
拆分出來的部分,可稱為子系統(tǒng)或模塊,其應(yīng)完成一個相對對立的功能,并且與其他子系統(tǒng)/模塊之間的關(guān)系很簡單。其獨立性是模塊化、抽象、信息隱藏和局部化概念的直接結(jié)果,具有獨立模塊的軟件容易開發(fā)、測試和維護。其獨立性通過兩項質(zhì)量標(biāo)準(zhǔn)來衡量:耦合和內(nèi)聚。
耦合 衡量不同模塊間相互依賴的緊密程度。也叫塊間聯(lián)系。它是對一個軟件結(jié)構(gòu)內(nèi)不同模塊之間互連程度的度量。它取決于各個模塊之間接口的復(fù)雜程度、進入或訪問一個模塊的點以及哪些信息通過接口傳遞。在設(shè)計上,應(yīng)該追求“低耦合”,即拆分單元之間應(yīng)該是業(yè)務(wù)隔離性比較大的,相互依賴度不高。 內(nèi)聚 衡量一個模塊內(nèi)部各元素彼此結(jié)合的緊密程度。在設(shè)計上,需要追求“高內(nèi)聚”,即劃分單元的業(yè)務(wù)邊界清晰,其內(nèi)部的業(yè)務(wù)相關(guān)性很高、依賴性很高的。
研發(fā)成本高 這種方式,依然存在代碼到處拷貝的問題。為了實現(xiàn)某單一功能(例如數(shù)據(jù)庫訪問),不得不在各處自己來實現(xiàn)。這無形中導(dǎo)致了代碼的拷貝。 復(fù)雜度擴散 因各部分獨立實現(xiàn),當(dāng)面臨同一技術(shù)問題時,不得不都要去考慮。例如隨著數(shù)據(jù)量增大、并發(fā)訪問越來越高,用戶的數(shù)據(jù)庫訪問成為瓶頸。此時可考慮通過增加緩存來降低讀壓力,對于這一架構(gòu)上的調(diào)整,各業(yè)務(wù)線都需要關(guān)注其導(dǎo)致的復(fù)雜性。 業(yè)務(wù)耦合度高 如業(yè)務(wù)系統(tǒng)間復(fù)用了部分代碼,則如果業(yè)務(wù)A需要升級,業(yè)務(wù)B將不得不面臨被動升級的窘境。雖然可以通過拷貝代碼方式解決,但又會造成代碼冗余等問題。 故障隔離性差 如某業(yè)務(wù)系統(tǒng)出現(xiàn)問題,將很有可能會影響其關(guān)聯(lián)調(diào)用的其他業(yè)務(wù)系統(tǒng),進而導(dǎo)致更多的業(yè)務(wù)線受影響。此外,從數(shù)據(jù)庫層面也存在類似問題,因各業(yè)務(wù)系統(tǒng)復(fù)用同一數(shù)據(jù)庫,當(dāng)某性能較差的語句拖垮整個數(shù)據(jù)庫時,影響的可能是所有業(yè)務(wù)線。 上述問題的核心是沒有獨立的服務(wù)層。
為應(yīng)對上述的問題,可將業(yè)務(wù)功能都獨立成服務(wù)。服務(wù)就意味著要對外提供開放的能力,當(dāng)其他系統(tǒng)需要使用這項功能時,無須定制化開發(fā),直接引用即可。這種架構(gòu)方式,可簡稱為SOA。SOA的全稱是Service Oriented Architecture,中文翻譯為'面向服務(wù)的架構(gòu)'。SOA的出現(xiàn),解決了企業(yè)內(nèi)部多種業(yè)務(wù)系統(tǒng)的整合,這些系統(tǒng)可能異構(gòu)、實現(xiàn)技術(shù)不同,但均可通過服務(wù)化完成整合,提高了業(yè)務(wù)系統(tǒng)的建設(shè)效率。
面向服務(wù)的分布式計算 服務(wù)間松散耦合 支持服務(wù)的組裝
服務(wù)注冊與自動發(fā)現(xiàn)
以服務(wù)契約方式定義服務(wù)交互方式
松耦合的目的是減少各個服務(wù)間的依賴和互相影響。因為采用 SOA 架構(gòu)后,各個服務(wù)是相互獨立運行的,甚至都不清楚某個服務(wù)到底有多少對其他服務(wù)的依賴。如果做不到松耦合,某個服務(wù)一升級,依賴它的其他服務(wù)全部故障,這樣肯定是無法滿足業(yè)務(wù)需求的。但實際上真正做到松耦合并沒有那么容易,要做到完全后向兼容,是一項復(fù)雜的任務(wù)。 中心化(ESB模式) ESB的全稱是Enterprise Service Bus,中文翻譯為'企業(yè)服務(wù)總線'。ESB將企業(yè)中各個不同的服務(wù)連接在一起。因為各個獨立的服務(wù)是異構(gòu)的,如果沒有統(tǒng)一的標(biāo)準(zhǔn),則各個異構(gòu)系統(tǒng)對外提供的接口是各式各樣的。SOA使用ESB來屏蔽異構(gòu)系統(tǒng)對外提供各種不同的接口方式,以此來達到服務(wù)間高效的互聯(lián)互通。ESB這樣一個中心服務(wù)總線,提供了對各種技術(shù)接口(HTTP、Socket、JMS、JDBC等)的適配接入、數(shù)據(jù)格式轉(zhuǎn)換、數(shù)據(jù)裁剪、服務(wù)請求路由等功能。核心目的是讓企業(yè)客戶能基于這些SOA的產(chǎn)品實現(xiàn)系統(tǒng)間的互聯(lián)互通,同時提高開發(fā)集成效率,更快地實現(xiàn)SOA項目的落地。這一架構(gòu)解決的根本訴求是實現(xiàn)異構(gòu)系統(tǒng)之間的交互。 去中心化 去中心化除了對SOA特性的實現(xiàn)和滿足外,相比'中心化'的不同主要就是服務(wù)提供者和服務(wù)調(diào)用者之間在進行服務(wù)交互時無需通過任何服務(wù)路由中介,避免因為'中心點'帶來的平臺難擴展的問題及潛在的雪崩風(fēng)險。但對于不同技術(shù)接口的支持、數(shù)據(jù)格式轉(zhuǎn)換、服務(wù)動態(tài)路由等功能沒有前者好,更多需要依靠服務(wù)應(yīng)用的編寫來滿足這樣的需求。
- 傳統(tǒng)ESB模式的服務(wù)調(diào)用方式是,每一次服務(wù)的調(diào)用者要向服務(wù)器提供者進行服務(wù)交互請求時都必須通過中心的ESB來進行路由。經(jīng)過服務(wù)總線路由過的服務(wù)交互,共出現(xiàn)4次網(wǎng)絡(luò)會話創(chuàng)建和數(shù)據(jù)傳輸。而通過'去中心化'服務(wù)架構(gòu)中的服務(wù)交互,一次服務(wù)的調(diào)用只有2次網(wǎng)絡(luò)會話創(chuàng)建和數(shù)據(jù)傳輸,網(wǎng)絡(luò)開銷降低一半。從邏輯上看,所有服務(wù)調(diào)用都通過服務(wù)總線,服務(wù)總線的訪問和計算壓力都會非常大。另外,所有業(yè)務(wù)都通過服務(wù)總線的方式,則服務(wù)調(diào)用量比較大,所需的網(wǎng)絡(luò)帶寬要求非常高,甚至?xí)霈F(xiàn)超過目前網(wǎng)絡(luò)設(shè)備的能力范圍。
- '中心化'架構(gòu)可能給平臺帶來災(zāi)難性的'雪崩'效應(yīng)。且一旦遇到雪崩之后,故障恢復(fù)的時間和成本都非常高昂。正因為雪崩隱患存在,某種程度上束縛了中心化服務(wù)框架的平臺擴展能力。也就是說,增加中心點企業(yè)服務(wù)總線實例的節(jié)點數(shù)量,并不能線性擴展平臺的服務(wù)能力。'去中心化'服務(wù)框架可以避免因為個別問題波及整個平臺的業(yè)務(wù)受影響,最多也只是部分服務(wù)出現(xiàn)問題,就算出現(xiàn)問題也更容易定位問題和故障恢復(fù)。
微服務(wù)架構(gòu),是近些年來頗為流行的一個架構(gòu)方式。從我來看,它更多的是服務(wù)化適應(yīng)互聯(lián)網(wǎng)化的產(chǎn)物,而不是取代服務(wù)化。下述內(nèi)容摘自極客時間-李運華的課程《從0開始學(xué)架構(gòu)》。服務(wù)粒度 整體上來說,SOA的服務(wù)粒度要粗一些,而微服務(wù)的服務(wù)粒度要細(xì)一些。 服務(wù)通信 SOA采用了ESB作為服務(wù)間通信的關(guān)鍵組件,負(fù)責(zé)服務(wù)定義、服務(wù)路由、消息轉(zhuǎn)換、消息傳遞,總體上是重量級的實現(xiàn)。微服務(wù)推薦使用統(tǒng)一的協(xié)議和格式,例如,RESTful協(xié)議、RPC協(xié)議,無須ESB這樣的重量級實現(xiàn)。 服務(wù)交付 SOA對服務(wù)的交付并沒有特殊要求,因為SOA更多考慮的是兼容已有的系統(tǒng);微服務(wù)的架構(gòu)理念要求'快速交付',相應(yīng)地要求采取自動化測試、持續(xù)集成、自動化部署等敏捷開發(fā)相關(guān)的最佳實踐。如果沒有這些基礎(chǔ)能力支撐,就難以達到快速交付的要求,部署的成本呈指數(shù)上升。 應(yīng)用場景 SOA更加適合于龐大、復(fù)雜、異構(gòu)的企業(yè)級系統(tǒng),這也是SOA誕生的背景。這類系統(tǒng)的典型特征就是歷時間久、技術(shù)棧不同、來源各異,無法大規(guī)模優(yōu)化或重構(gòu)。因為成本和影響太大,只能采用兼容的方式進行處理。微服務(wù)更加適合于快速、輕量級、基于Web的互聯(lián)網(wǎng)系統(tǒng),這類系統(tǒng)業(yè)務(wù)變化快,需要快速嘗試、快速交付;同時基本都是基于Web,雖然開發(fā)技術(shù)可能差異很大,但對外接口基本都是提供HTTP RESTful風(fēng)格的接口。
服務(wù)管控 在分布式服務(wù)體系下,服務(wù)鏈路跟蹤、鏈路分析、實時業(yè)務(wù)指標(biāo)的監(jiān)控等問題,也都是實現(xiàn)微服務(wù)架構(gòu)時一定會面臨的問題,擴大到更大范圍就是整體服務(wù)平臺的管控能力。 分布式事務(wù) 需要針對業(yè)務(wù)的需求在事務(wù)一致性和性能間做好平衡,一套穩(wěn)定、成熟的分布式事務(wù)解決方案也是構(gòu)建微服務(wù)框架首先要考慮的技術(shù)問題。 自動化運維 微服務(wù)化后,較之前的部署方式,從服務(wù)器的數(shù)量以及服務(wù)交互復(fù)雜程度上都上升一個數(shù)量級,原有運維工具和平臺是否能夠支撐需要好好考慮。 服務(wù)設(shè)計 微服務(wù)中服務(wù)邊界的劃分一定是從業(yè)務(wù)的維度,以什么樣的服務(wù)顆粒度定義服務(wù)?以什么樣數(shù)據(jù)模型支撐服務(wù)能力的線性擴展?如何設(shè)計服務(wù)具有很好的業(yè)務(wù)前瞻性? 組織架構(gòu) 服務(wù)強調(diào)持續(xù)的演變,需要組建對應(yīng)的組織或者對現(xiàn)有的組織架構(gòu)進行調(diào)整,圍繞以服務(wù)為中心的持續(xù)運營,這對很多企業(yè)原有的信息中心架構(gòu)師不小的沖擊。
服務(wù)劃分過細(xì),服務(wù)間關(guān)系復(fù)雜 服務(wù)劃分過細(xì),單個服務(wù)的復(fù)雜度確實下降了,但整個系統(tǒng)的復(fù)雜度卻上升了,因為微服務(wù)將系統(tǒng)內(nèi)的復(fù)雜度轉(zhuǎn)移為系統(tǒng)間的復(fù)雜度了。從理論的角度來計算,n個服務(wù)的復(fù)雜度是n×(n-1)/2,整體系統(tǒng)的復(fù)雜度是隨著微服務(wù)數(shù)量的增加呈指數(shù)級增加的。
服務(wù)數(shù)量太多,團隊效率急劇下降 微服務(wù)的'微'字,本身就是一個陷阱,將服務(wù)拆分得很細(xì)。這樣做給工作效率帶來了明顯的影響。一個簡單的需求開發(fā)就需要涉及多個微服務(wù)。無論是設(shè)計、開發(fā)、測試、部署,都需要工程師不停地在不同的服務(wù)間切換。 調(diào)用鏈太長,性能下降 由于微服務(wù)之間都是通過HTTP或者RPC調(diào)用的,每次調(diào)用必須經(jīng)過網(wǎng)絡(luò)。在很多高性能業(yè)務(wù)場景下是難以滿足需求的。為了支撐業(yè)務(wù)請求,可能需要大幅增加硬件,這就導(dǎo)致了硬件成本的大幅上升。 調(diào)用鏈太長,問題定位困難 系統(tǒng)拆分為微服務(wù)后,一次用戶請求需要多個微服務(wù)協(xié)同處理,任意微服務(wù)的故障都將導(dǎo)致整個業(yè)務(wù)失敗。然而由于微服務(wù)數(shù)量較多,且故障存在擴散現(xiàn)象,快速定位到底是哪個微服務(wù)故障是一件復(fù)雜的事情。 沒有自動化支撐,無法快速交付 如果沒有相應(yīng)的自動化系統(tǒng)進行支撐,都是靠人工去操作,那么微服務(wù)不但達不到快速交付的目的,甚至還不如一個大而全的系統(tǒng)效率高。 沒有服務(wù)治理,微服務(wù)數(shù)量多了后管理混亂 隨著微服務(wù)種類和數(shù)量越來越多,如果沒有服務(wù)治理系統(tǒng)進行支撐,微服務(wù)提倡的輕量化就會變成問題。如果以上場景都依賴人工去管理,整個系統(tǒng)將陷入一片混亂,最終的解決方案必須依賴自動化的服務(wù)管理系統(tǒng)。 領(lǐng)域驅(qū)動設(shè)計,簡稱DDD(Domain-Driven Design)。DDD是用來解決負(fù)責(zé)業(yè)務(wù)場景的。如果是簡單業(yè)務(wù)場景,可使用簡單的事務(wù)腳本解決;但對于復(fù)雜業(yè)務(wù)場景,這種方式就不再適用。因為一旦業(yè)務(wù)變得復(fù)雜,事務(wù)腳本就很難應(yīng)對,容易造成代碼的“一鍋粥”,系統(tǒng)的腐化速度和復(fù)雜性呈指數(shù)級上升。目前比較有效的治理辦法就是領(lǐng)域建模,因為領(lǐng)域模型是面向?qū)ο蟮?,在封裝業(yè)務(wù)邏輯的同時,提升了對象的內(nèi)聚性和重用性,因為使用了通用語言,使得隱藏的業(yè)務(wù)邏輯得到顯性化表達,使得復(fù)雜性治理成為可能。業(yè)務(wù)服務(wù)中臺,其本質(zhì)是服務(wù)化的延伸。從早期的”API as Service”,過渡到” Product as Service”乃至” Solution as Service”。方式上仍然是通過拆分業(yè)務(wù)解決系統(tǒng)的復(fù)雜性,通過服務(wù)共享來提供可重用性,通過服務(wù)化來達到業(yè)務(wù)支持的敏捷性;通過統(tǒng)一的數(shù)據(jù)架構(gòu)來消除數(shù)據(jù)交互的屏障。其核心在于業(yè)務(wù)支持能力的構(gòu)建,重點是在于提高業(yè)務(wù)效率,提升業(yè)務(wù)創(chuàng)新力。 從設(shè)計層面,主要是要遵循面向?qū)ο蟮姆治龊驮O(shè)計的方法。 從運營層面,服務(wù)中心應(yīng)該是一個完整的業(yè)務(wù)模型,要有數(shù)據(jù)運營和業(yè)務(wù)整合的價值。 從工程層面,服務(wù)中心是基于分布式架構(gòu),解決了在大規(guī)模應(yīng)用上的問題。
(歡迎大家加入數(shù)據(jù)工匠知識星球獲取更多資訊。)
|