首頁>技術>

如果問架構師什麼是架構,可能會得到很多不同的答案,每個架構師對“架構”都有不一樣的理解,當然這不分對錯。資料架構、應用架構、部署架構、高效能架構、高可用架構、高擴充套件架構等都是架構,每一種架構都有應用場景,有不同的技術方法、特徵及要求,但我覺得有一個核心的概念是共同的:架構必定是在長期的生產過程中,經過架構師深刻的總結和思考,積累下來的最佳實踐和可複用的合理抽象。能夠應對複雜挑戰的架構在過去、現在及未來都是架構師所向往和追求的理想目標。

為什麼我們要研究思考這個問題

此前無意中在阿里巴巴泰山版Java開發手冊裡面看到關於系統設計可擴充套件性的一段話,談到設計可擴充套件性的本質是找到系統的變化點,並隔離變化點;極致擴充套件性的標誌,就是需求新增時,無需在原有程式碼交付物上進行任何形式的修改。這段話是阿里技術架構師的經驗總結,他們用實際案例告訴我們,想要實現業務的快速支撐,系統的可擴充套件能力不可忽視

對於大多數架構師而言,可擴充套件的系統架構設計有一個樸素的認識,就是解決服務橫向擴充套件、容量、可用性及效能瓶頸問題,雖簡單粗暴,卻也是最有效的方式,就是我們俗稱的“加機器”。這一認識,在實際生產運作中,變成了一種很普遍的做法。對於一個規模和資料量都迅速增長的系統而言,高效能和高可用問題自然是我們要優先考慮的。但是隨著時間的推移,業務的不斷髮展,面臨的業務場景越來越複雜,為了解決這些複雜的業務問題,我們的實現方案也越來越複雜,理解、維護、迭代的難度隨之增加,加速了系統腐化速度。

最終擺在我們面前的問題,除了要解決效能慢與體驗差的問題,還需要面對功能與程式碼指數級增長帶來的系統擴充套件性問題以及業務變化帶來的差異化服務問題。而很多系統,在架構設計時並未充分考慮到這些問題,存在平臺程式碼和業務程式碼耦合嚴重難以分離、業務和業務之間程式碼交織缺少拆解的現象,導致系統的重構、程式碼推倒重來成為常態,從而影響業務交付能力,還浪費人力財力。

同樣在實際開發過程中,可擴充套件性問題也經常被開發人員忽略掉,滿足業務需求最簡單的處理,就是在程式碼中用“if else”分支來處理自己的邏輯思維,“if else”是開發人員寫程式碼時,使用頻率最高的關鍵詞之一,然而有時過多的“if else”會讓我們感到腦殼疼。當我們去review程式碼時,都會發現類似一個業務處理類上萬行程式碼,一個函式方法上千行程式碼的場景。缺少元件化、程式碼隔離,通常都是直接在核心程式碼中逐塊增加業務程式碼,這種寫法在很短時間內會讓核心服務“太胖”,複用性較差甚至無法複用,核心程式碼的頻繁變動,需要全量部署釋出,容易導致版本不穩定、代價高、風險大。

根據實際經驗總結,不論從程式碼質量、可讀性、可擴充套件性還是從可維護性、開發效率方面看,缺少程式碼抽象、擴充套件性考慮,採取簡便直接上線的方法所需的額外返工,從長遠來看都會很糟糕。

在聊架構的時候,我們一定需要聊一聊架構設計的目的,在我看來,為什麼要實現架構設計,用一句話來概括就是"架構設計的真正目的是為了解決系統的複雜度帶來的問題,控制好複雜度,就可快速實現業務創新。"我們往往有“為了高效能、高可用、高擴充套件,所以要做架構設計”這樣的想法並在實際當中這麼做,不管什麼系統,不管什麼業務場景,上來就要去“三高”,那麼將非常有可能會讓架構設計過於複雜,專案落地遙遙無期。歷盡千辛萬苦,最終客戶不滿意,老闆不高興,那也是白搭了。

至此,我們簡單的對為什麼要研究思考高擴充套件架構進行了說明,可擴充套件性是衡量架構設計好與壞的一個重要因素,但是一個系統要在一開始就設計出比較好的可擴充套件性是有一定難度的,可擴充套件性體現在不同層次、不同維度上,有大有小,它不是個體行為,需要依靠團隊共同完成。任何系統最開始相對都是簡單的,隨著業務增加,慢慢開始變的複雜起來。我們需要在這個循序漸進的過程中,在極其不確定的業務變化中,尋找到真正的可擴充套件點,讓架構具備高擴充套件性。

實現高擴充套件架構的目標、原則和方法是什麼?

擴充套件性涉及面非常廣,突破系統架構的擴充套件性約束是構建複雜業務系統必須解決的難題之一。一份良好可擴充套件的架構方案絕對是無價的,我們定義高擴充套件架構的目標是讓系統架構簡單清晰、應用系統間耦合低、容易水平擴充套件、業務功能增改方便快捷,實現服務/模組/程式碼級動態化、熱插拔管理機制,提高研發效率,快速響應業務需求,提升客戶感知。

在系統擴充套件性設計方面我們定義了幾個關鍵原則:

1、解耦拆分原則:穩定部分與易變部分分離;核心業務與非核心業務分離;主流程與輔流程分離;應用與資料分離;服務與實現細節分離。

2、松耦合原則:跨域呼叫非同步化,不同業務域之間儘量非同步解耦。非核心業務儘量非同步化,核心和非核心業務之間,儘量非同步解耦。

3、服務依賴原則:核心服務不依賴非核心服務;非核心服務可依賴核心服務;穩定部分不依賴易變的部分、容易變的部分可以依賴穩定的部分。

4、服務自治原則:服務能彼此獨立修改、部署、釋出和管理。避免引發連鎖反應。

對於實施可擴充套件架構,一些簡單而有效的方法:

1、要定義規範:明確程式碼擴充套件性規範與約束,給出示例,引導開發人員在實現業務邏輯時,能夠進行結構化、抽象化思考,保障程式碼的可維護性和可讀性。

2、要搭好基礎框架:高擴充套件架構有很多成功的案例,但實施起來沒有標準,不能複製,也難以衡量,所以我們需要結合我們自身規範,自身需求,搭建基礎框架,降低技術門檻,讓開發人員關注業務邏輯編碼。

3、要引入設計模式:應用面向物件思想,原則,使用常見設計模式,進行程式碼層面的設計。

4、要找到擴充套件點:結合業務需求,識別易變化的點,梳理擴充套件點清單,對於存在業務變動的程式碼,利用擴充套件點重構原有程式碼,抽象穩定基礎能力。

5、要做好程式碼審查:對程式碼的審查內容很多,在關注程式碼的編寫是否規範、技術處理規範、業務邏輯實現等的同時,考慮擴充套件設計來阻止程式碼腐化。

為了實現高擴充套件的架構,我們做了哪些實踐?

基於上述考慮,我們今年在一些新產品、新專案建設過程中,做了一些關於可擴充套件性架構的實踐,嘗試對傳統架構模式進行變革,為後續打造新一代產品架構做好準備。

高擴充套件實踐一:透過領域分層設計,將業務規則分離出來,抽象在領域層,提升系統的可讀性、複用性和擴充套件性。

傳統三層架構,非常簡單,基本沒有太多開發門檻,在它帶來便捷的同時,也帶來了一些不利因素,其中之一就是開發人員缺乏對業務場景的深度理解以及對該類問題的抽象思考,當再次遇到同類功能時,都需要重複做一遍。長此以往,相似的程式碼模組也會很多,十分不利於系統的升級維護。

在我們已有的微服務架構中,我們嘗試著以一種更輕量級的領域設計來融合到微服務系統設計中。透過領域模式的核心思想,來管理業務域的核心邏輯,在概念上保留領域物件、基礎設施、領域服務、領域事件,同時領域物件採用貧血模型,透過領域方法來描述領域能力,邏輯功能高度內聚。同時,在領域服務層,我們分離讀和寫,只有寫服務依賴領域能力來實現核心的狀態變更,讀服務直接基於基礎設施層來提供能力。分層架構示意圖如下:

透過這樣的分層,我們在層次間的依賴上面,保持了足夠的靈活性;而在核心的業務邏輯上,也具備領域能力的高度內聚,保證了一定的複用性和擴充套件性。同時,也降低了對開發人員的要求,讓對領域模型理解不深的人員也能保證一定的完成質量。系統實際分層架構如下圖所示:

基於領域模式實現功能時,經常遇到的問題之一,是哪些邏輯應該放在領域內?如果把所有業務邏輯都放到領域內,那過度膨脹的領域就失去了自身表達的意義。我們在實踐中,通常會先將業務邏輯拆分為原子的功能點和控制流程,將明確屬於領域內的邏輯合併,將不明確的功能點放在應用層,在後續迭代中再根據業務沉澱模型能力。

在分層設計實現中,我們需要將領域邏輯與業務場景流程控制分離。在領域層實現核心業務功能;在應用層透過流程控制聚合各個領域,實現特定業務場景,同時在應用層實現不屬於領域內的業務場景細節邏輯。流程控制方面需要結合業務,原則上以簡潔實用為主,保證既能滿足業務功能,又能保持擴充套件性和可讀性。在我們業務中,大部分業務場景是基於領域能力組合實現,少部分業務場景我們引入了輕量流程引擎、狀態機、規則引擎、策略控制模式等。

DDD雖然有很多優點,但是我們在實踐和持續迭代過程中也遇到一些問題。最明顯的問題是DDD對設計人員要求較高,需要設計人員對領域模型和業務知識有較深入的思考與理解,才能設計出符合領域規範的實現方案。在理解不充分時,會出現生搬硬套現象,程式碼最終的實現往往會變成“四不像”,不僅不能合理表達領域的能力,而且還會因為未正確實現約束導致程式碼混亂。

高擴充套件實踐二:面向功能拆分,產生微核心架構,實現業務和平臺分離、業務和業務分離。

以最近我們新上線的促銷中心為例講解高擴充套件性系統設計與實現。促銷中心是一個平臺型的業務系統,要做到業務與業務的隔離、業務與平臺的隔離。

為了達成這個目標,我們自研了一套外掛框架,促銷中心基於這個框架構建了促銷業務排程框架及業務外掛庫。接入這個框架後,平臺邏輯和業務邏輯得到了分離,各種促銷型別(滿減、優惠等)之間的邏輯也不再耦合,而是變成jar包級別隔離,同時支援了基於促銷型別(策略)的動態路由模式。

促銷平臺核心程式負責促銷計算初始化、促銷規則執行、促銷記錄生成、促銷分析等,實現了由主流程框架統一進行排程。我們把各種型別促銷業務從核心程式中單獨抽取出來,做成一個個業務外掛。透過這種方式,也將核心程式和應用程式徹底進行了分離。核心程式和應用程式是透過介面聯絡起來,這層介面都是“宣告”,包括介面定義、資料物件的定義和擴充套件點的預設執行策略定義等。促銷平臺架構如下圖所示:

此外,外掛框架支援在應用不停的情況下新增、更新、解除安裝業務外掛,無感知進行升級,滿足業務快速上線要求,系統更加穩定性、業務接入更加容易。各業務系統統一使用外掛框架提供的外掛包釋出頁面,完成業務外掛包的裝載。流程如下圖所示:

高擴充套件實踐三:搭建業務能力運營平臺,實現管理域和執行域分離架構,讓業務快速接入、快速擴充套件。

管理域指的是系統業務管理員配置業務流程、引數、規則或業務擴充套件點的實現工具的程式碼執行空間。執行域指的是系統業務邏輯處理程式的程式碼執行空間,為了支撐實際業務執行而存在的,而管理域則是為了對執行域的動態調整控制而存在的。

在應用的分層架構中,我們可以從使用者能夠接觸的層次往系統抽象層次依次分為:頁面、功能、能力、資料模型。在不同的業務場景下,有大量的業務模組是可以在這四個維度中的某幾個進行共用的,那我們就可以在架構上做一項考慮:把每一個應用中的頁面、功能、能力和資料模型都打散,分別沉澱到對應的頁面、功能、能力、資料模型的共性庫中,這樣以後每次來一個新的業務只要透過從共性庫中選擇自己所需要的頁面、功能、能力、資料模型就可以快速搭建匹配特定業務邏輯的應用。

按管理和執行域劃分,頁面、功能、能力、資料模型都是屬於執行域的內容,而由於這些內容在業務不斷的演化過程中會越來越豐富,所以我們需要提供一個平臺來對這些內容進行管理,隨之管理域就出現了。如圖基於管理域和執行域分離的應用架構示意:

在管理域中有如下三個基礎功能模組:元資料管理、能力管理、元件管理。

首先,元資料管理主要完成對資料模型的管理,包括對內建物件的資料結構進行擴充套件、部分欄位的定義,也包括對應用中的業務物件進行定義、欄位設定等功能,在整個業務邏輯中元資料只是作為配置引數存在。

其次,能力管理主要是實現能力運營及功能擴充的管理,主要包括兩部分,第一是對如業務系統透出的能力進行註冊和發現,第二是給業務系統預留介面,可讓應用自己進行定製化開發實現業務邏輯,再透過機制進行註冊和發現並提供給應用使用。具體的實現機制可參考 Java 中的 SPI 機制,簡單來說步驟如下:首先在程式碼中使用統一註解,透過掃描可以自動把註解部分的程式碼上報到能力管理實現註冊;在能力對應的程式碼進行修改了之後,掃描機制也能在一定的時機進行更新;然後透過統一的編碼規範,對某些類預留抽象類,可暴露給應用方自己進行實現;應用方對抽象類進行實現後,可透過掃描機制發現,並讓應用進行呼叫。

最後,元件管理主要可以分為頁面元件服務元件的管理。

前端的元件最終是以頁面編輯器的方式進行實現,在此不做詳細表述,而管理後臺的頁面元件庫則需要與全域性管理中的資源、選單、角色管理配合滿足業務的需求。其核心業務邏輯在於,所有系統中的頁面、選單、頁籤、按鈕以及其它頁面元素都可以由統一的提供方提供,放到公共庫中,使用方只需要按照標準進行呼叫即可,能夠實現最大限度的資源複用。

功能服務元件則是把業務和平臺分離的關鍵,大量具有業務特性的聚合服務從核心業務邏輯中抽離,形成一個一個的服務元件,以外掛的方式裝配到主幹業務流程中,由於使用統一的標準進行開發,在業務元件中預設大量的配置項,透過自動註冊和發現機制實現配置項自動化上報,而元件一被生產方生產出來後就會進入統一的服務元件庫中,能夠被任一業務方進行呼叫。

透過以上三個能力,能夠實現對資料模型、能力、功能以及頁面的統一管理的需求,只是對這些內容管理還是不夠的,不能實現最終目的,在能夠對其進行管理之後,我們需要能夠按業務需求透過配置化、低程式碼的方式把這些內容組裝拼接起來,以滿足業務的實際需求。

為了解決不同業務動態化配置的問題我們需要引入業務身份這一概念,業務身份主要是把前後臺的應用放在同一個空間下進行管理,我們透過管理域可在相應業務身份下進行業務邏輯的配置,這些配置可以讓系統中包含的各個應用在執行域時能夠識別所需要使用的頁面、功能、能力和資料模型,能很好地運用業務身份進行業務邏輯的擴充套件。

總結展望

高擴充套件性”作為今年我們團隊的三大架構研究方向之一,結合實際專案已經有了應用落地,目前業務系統已上線執行,我們正在積極將實踐框架和經驗複製到更多的產品上。基於框架能夠實現增量式開發、增量式釋出,解決了一直以來業務系統程式碼交織耦合、難以拆解的困擾。在程式碼質量和開發效率上也取得了顯著提升,業務支撐更加敏捷、快速迭代。

“沒有最好,只有最合適!”回到最開始說的那句話,架構設計的真正目的是為了解決系統的複雜度帶來的問題,不是為了追求所謂的高大上。就像任何一種複雜的架構一樣,解決擴充套件性問題都不存在什麼銀彈。以業務需求作為指引,做出權衡和妥協對於實現高擴充套件性來說至關重要。高擴充套件性設計不僅僅是一個技術問題,它更像是一種模式,可以是思維模式,也可以是執行模式。高擴充套件架構是我們繼續努力的方向,我們將持續進行探索。

4
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • leetcode1208_go_儘可能使字串相等