深入淺出雲原生架構(一):架構演進與成熟

本文要點

  • 如果急於推行微服務,可能會出現架構不穩定鴻溝和反模式。
  • 瞭解歷史上範式轉型過程中的弊端和陷阱,應該使我們能夠從以前的錯誤中吸取教訓,並使組織能夠在最新的技術浪潮中蓬勃發展。
  • 重要的是要了解不同架構風格(例如單體應用、微服務和無服務器函數)的利弊。
  • 架構演進的重複週期:人們在推行新範式的初期還不瞭解最佳實踐,結果堆積了更多技術債務。隨着行業開發出新模式以填補缺陷,團隊也開始採用新的標準和模式。
  • 應將架構模式視爲策略,這些策略有利於技術快速發展,並保護業務應用免受變化影響。

近年來,諸如微服務、雲計算和容器化之類的技術趨勢一直在迅速發展,其中大多數技術現在已成爲高級IT工程師、架構師和管理層日常工作的一部分。

我們生活在一個雲技術已然普及的世界中。但是,轉向雲計算並不意味着成爲雲原生形態。實際上,在沒有實現雲原生形態之前就轉向雲計算可能是很危險的舉動。

我們要研究這些趨勢,並探討企業應該實施怎樣的架構和組織變革才能充分利用雲計算的優勢;但在此之前,重要的是要了解我們的過去,我們的現狀以及我們前進的方向。

瞭解歷史上範式轉型過程中的弊端和陷阱,應該使我們能夠從以前的錯誤中吸取教訓,並使組織能夠在最新的技術浪潮中蓬勃發展。

反模式

我們會簡要介紹這一演變過程,其中會探索反模式的概念;所謂反模式,指的是在應對重複出現的問題時,習慣使用的措施往往無效甚至可能適得其反。

這個文章系列將具體論述上面提到的反模式。

架構演變

在過去大約50年中,軟件架構和應用程序託管模型經歷了從大型機到微服務和無服務器的重大轉變。

圖1顯示了架構模型的演化及其所推動的範式。

圖1:從大型機到雲和微服務的架構演變

中心化

上世紀70到80年代,大型機統治了計算領域。大型機基於中心化數據存儲和計算模型,而客戶端終端只具備基礎功能,用來在早期的屏幕上輸入和顯示數據。

最早的大型計算機使用打孔卡,並且大多數計算都在批處理流程中進行。由於沒有任何事物是實時處理的,因此也沒有在線處理能力,並且延遲爲100%。

隨着在線處理和用戶界面終端的誕生,大型機範式發生了一些變化。但是,安裝在組織大型機房中的大規模中央處理單元,其整體範式仍然採用“不變應萬變”的方法,並且只能提供大多數業務應用所需功能的一部分。

中心化 -> 去中心化

客戶端/服務器架構將大多數邏輯放在服務端,只將某些處理過程放在客戶端上。客戶端/服務器是分佈式計算的首次嘗試,意圖取代大型機作爲業務應用的主流託管模型的地位。

在這一架構誕生的最初幾年中,開發社區仍在使用與大型機應用開發相同的流程和單層原則來爲客戶端/服務器編寫軟件,從而產生了諸如意大利麪條代碼胖球之類的反模式。軟件的這種有機成長也產生了其他一些反模式,例如大泥球。業界必須找到一些方法,阻止團隊遵循這些不良實踐;爲此人們需要研究,編寫良好的客戶端/服務器代碼必需哪些內容。

這項研究工作找出了幾種反模式,以及設計和編碼模式的最佳實踐。它引入了一項稱爲面向對象程序設計(OOP)的重大改進,其具有繼承、多態性和封裝功能,以及處理分散數據的範式(相比之下大型機只有一個真相版本),並提供了行業應如何發展以應對新挑戰的指南。

客戶端/服務器模型基於三層架構,包括表示(UI)、業務邏輯和數據層。但是,大多數應用程序是用兩層模型編寫的,其中一個胖客戶端將所有表示、業務和數據訪問邏輯封裝在一起,並直接訪問數據庫。儘管彼時業界已經開始討論將表示層與業務和數據訪問分離的必要性,但這種做法直到基於互聯網的應用問世,才真正顯示出了自己的必要性。

總的來說,這種模型是對大型機範式侷限的一種改進,但是業界很快也撞上了前者的圍牆和侷限,例如需要在每臺用戶計算機上安裝客戶端應用,並且無法作爲業務函數進行細粒度的擴展等。

去中心化->連接/共享(www)

90年代中期發生了互聯網革命,隨即誕生了一個全新的範式。Web瀏覽器成爲了客戶端軟件,而Web和應用程序服務器負責託管所有的處理和邏輯。萬維網(www)範式在Web服務器上託管表示(UI)代碼,在應用服務器上託管業務邏輯(API),並在數據庫服務器中存儲數據,從而塑造了真正的三層架構。

開發社區開始從胖(桌面)客戶端遷移到瘦(Web)客戶端上,這主要是由面向服務構(SOA)之類的理念所推動的,這種理念加強了對三層架構的需求,並從客戶端技術的改進及Web瀏覽器的快速發展中汲取了動力。這一運動加快了產品上市速度,並且不需要安裝客戶端軟件。但是開發人員仍在使用緊密耦合的軟件設計,結果帶來了混亂(Jumble)等許多反模式。

作爲迴應,業界提出了改進的三層架構和實踐,諸如領域驅動設計(DDD)企業集成模式(EIP)、SOA和鬆散耦合技術等。

虛擬機託管->雲託管

21世紀的前十年見證了應用託管模式的重大轉變,此時託管開始成爲以雲計算的形式提供的一種服務。與傳統基礎架構相比,雲託管能以合理的成本,更容易地提供應用程序用例所需的託管、分佈式計算、網絡、存儲和計算等功能。此外,消費者也在利用資源的彈性來按需擴大或縮小規模。他們只需要爲所使用的存儲和計算資源付錢即可。

IaaS和PaaS中引入的彈性功能允許單個服務實例按需擴展,從而避免了爲了擴展性而複製實例的麻煩。但是,這些功能無法避免因其他目的(例如具有多個版本)或作爲單體部署副產品而導致的實例複製。

基於雲的託管的吸引力在於,開發和運營團隊用不着再操心服務器基礎架構了。它提供了三種託管選項:

  • 基礎架構即服務(IaaS):開發人員選擇託管其應用的服務器規格,而云則提供硬件、操作系統和網絡。這是這三種形式中最靈活的一種,但也確實給開發團隊帶來了一些負擔,因爲團隊必須指定服務器的規格參數。
  • 平臺即服務(PaaS):開發人員只需要操心他們的應用和配置。雲提供商負責所有服務器基礎架構、網絡和監視任務。
  • 軟件即服務(SaaS):雲提供商提供了託管在雲上的實際應用,這樣客戶端組織只需直接使用整個應用,甚至對應用代碼也不承擔任何責任。這一選項提供了開箱即用的軟件服務,但如果客戶需要的一些自定義業務功能不在服務提供商的選項之中,那麼這個選項就沒那麼靈活了。

PaaS成爲了幾種雲託管選項中的甜點,因爲它使開發人員可以託管自己自定義的業務應用,而不必操心基礎架構的準備或維護工作。

儘管雲託管鼓勵模塊化的應用設計和部署,但許多組織發現,提供商會引誘客戶將尚未針對彈性分佈式架構設計的老式應用直接遷移到雲中,從而產生了一種稱爲“單體地獄”的現代反模式。

爲了應對這些挑戰,業界提出了新的架構模式,例如微服務和12要素應用。

遷移到雲還給行業帶來了新的挑戰,那就是管理應用對第三方庫和技術的依賴關係。開發人員陷入了無窮無盡的選擇困境中,缺乏可靠的標準參照來選擇第三方工具,並且我們開始看到一些依賴地獄

依賴地獄可以發生在許多層面上:

  • :庫的依賴項(Java世界中的JAR和.NET世界中的DLL)若管理不當就可能導致問題。例如,典型的Spring Boot應用包含140多個庫JAR文件。我們需要確保在應用中沒有打包多餘的庫。
  • :需要闡明應用內部對象的所有依賴項。例如,一個Controller類依賴一個Business Service類,而這個Service類又依賴一個Repository類。我們需要在代碼審查期間花一些時間檢查應用中的依賴項,並確保沒有不正確的依賴項。
  • 服務:如果你在系統中使用微服務,請確認不同服務之間沒有直接依賴關係。

基於庫的依賴關係是一個打包挑戰,後兩個則是設計挑戰。本系列的後續文章將更詳細地研究這些依賴地獄的場景,並提供一些設計模式以避免產生意料之外的後果,防止技術膨脹。

微服務:細粒度的可複用性

諸如DDDEIP之類的軟件設計實踐自2003年左右就已誕生,一些團隊從那時起就將應用程序開發爲模塊化服務了,但是傳統的基礎架構(如用於Java應用程序的重量級J2EE應用程序服務器和用於.NET應用程序的IIS)對模塊化部署並無助益。

隨着雲託管的出現,尤其是諸如Heroku和Cloud Foundry之類的PaaS產品的面世,開發人員社區擁有了真正的模塊化部署和可擴展業務應用所需的一切。微服務變革由此興起。微服務爲細粒度、可複用的功能性和非功能性服務創造了可能性。

微服務在2013-2014年間開始愈加流行。微服務功能強大,可以使較小的團隊主導特定業務和技術功能的整個開發週期。開發人員可以隨時部署或升級代碼,而不會對系統的其他部分(客戶端應用程序或其他服務)產生不利影響。還可以根據需求在單個服務級別上按需縮放服務。

需要使用特定業務函數的客戶端應用程序將調用合適的微服務,而無需開發人員從頭開始編寫解決方案,或將解決方案打包爲應用程序中的庫。微服務方法鼓勵服務提供商和服務消費者之間以合約驅動開發工作。這樣可以縮短開發時間,並減少團隊之間的依賴性。換句話說,微服務使團隊之間的聯繫更加鬆散,並加速瞭解決方案的開發進程,這對組織,尤其是商業初創公司而言是至關重要的。

微服務還有助於在業務流程和領域(如客戶、訂單和庫存等)之間建立明確的界限。它們可以在被稱爲組織中“限界上下文”的垂直模塊內獨立開發。

這種變革還加快了其他良好實踐(如DevOps)的演進,並在組織級別提供了敏捷性和更快的面市時間。每個開發團隊將在其領域中擁有一個或多個微服務,並負責設計、編碼、部署到生產環境,以及生產後支持和維護的整個過程。

但是,就像之前的架構模型那樣,微服務方法也遇到了自己的問題。

人們開始敲打那些沒有從頭開始針對微服務設計的傳統應用,試圖迫使它們進入微服務架構,從而導致了被稱爲單體地獄的反模式。其他一些嘗試則強行將單體應用拆分爲幾個微服務,結果拆分出來的這些微服務在功能上不是相互孤立的,仍然嚴重依賴從同一單體應用中分解出來的其他微服務。這是稱爲微晶石(microlith)的反模式。

重點在於,我們要注意單體和微服務是兩種不同的模式,後者並不總是可以替代前者。如果我們不夠小心的話,最後可能會創建出一堆互相之間緊密耦合、混雜在一起的微服務。正確的選擇取決於針對應用程序功能的業務和可擴展性需求。

微服務爆發式發展過程中,另一個人們沒能料到的副作用是所謂的“死星”反模式。在服務交互和服務到服務的安全性(身份驗證和授權)方面,如果缺乏治理模型,微服務的泛濫通常會導致任何服務都可以隨意調用其他服務的狀況。想要找出有多少服務正在被各種客戶端應用程序以混亂的調用方式使用,這也是一項挑戰。

圖2顯示了像Netflix和Twitter這樣的組織如何陷入這種噩夢,並且不得不想出新的模式來應對“死星的死亡”問題。

圖2:由於缺乏治理的微服務爆炸式增長而導致的死星架構

儘管圖2中描述的示例看起來像是隻發生在巨頭身上的極端情況,但不要低估了雲反模式的指數級破壞力。業界必須學習如何操作一種史上最龐大的武器。富蘭克林·羅斯福曾說:“巨大的權力伴隨着重大的責任。”

諸如服務網格(service mesh)、邊車(sidecar)、服務編排和容器之類的新興架構模式可以有效地阻止基於雲的世界中出現的錯誤實踐。

組織應該瞭解並採用這些模式,宜早不宜遲。

快速瞭解關鍵的雲優先設計模式

服務網格

隨着雲平臺的面世,特別是出現了像Kubernetes這樣的容器編排技術後,服務網格就開始引起人們的關注了。服務網格是應用程序服務之間的橋樑,它帶來了許多附加功能,如流量控制、服務發現、負載平衡、彈性、可觀察性和安全性等。它使應用程序可以從應用程序級庫中卸載這些功能,並允許開發人員專注於業務邏輯。

諸如Istio之類的某些服務網格技術還支持諸如混沌注入之類的功能,以便開發人員可以測試他們的應用程序,以及多達數十種相互依賴的微服務的彈性和健壯性。

服務網格非常適合放在平臺即服務(PaaS)和容器即服務(CaaS)之上,並通過這些通用平臺服務提升推行雲計算過程的體驗。

之後的文章將深入探討基於服務網格的架構,並討論特定的用例,對比有無服務網格的不同解決方案。

無服務器架構

在過去的幾年中,另一個備受關注的趨勢是無服務器架構,也稱爲無服務器計算。無服務器比PaaS模型更進一步,因爲它將服務器基礎架構從應用程序開發人員那裏完全抽象出來了。

在無服務器中,我們將業務服務編寫爲函數,並將這些函數部署到雲基礎架構中。無服務器技術的一些例子包括Amazon LambdaSpring Cloud FunctionGoogle Cloud FunctionsMicrosoft Azure Functions等。

無服務器模型位於雲託管範圍內的PaaS和SaaS之間,如下圖所示。

圖3:雲計算、容器、服務網格和無服務器

與對比單體服務與微服務時的結論相似,並非所有解決方案都應作爲函數來實現。另外,我們不應使用無服務器函數替換所有微服務,就像我們不應替換所有單體應用,或將其分解爲微服務一樣。只有諸如用戶身份驗證或客戶通知之類的細粒度業務和技術功能,才應該設計爲無服務器函數。

根據我們應用程序的功能性和非功能性需求(例如性能和可伸縮性以及事務邊界等),我們應該爲每個特定用例選擇適當的單體、微服務或無服務器模型。常見的情況是,我們可能需要在一個解決方案架構中使用所有這三種模式。

如果設計不當,無服務器解決方案最終將變成納米片,其中每個函數都與其他函數或微服務緊密結合,並且無法獨立運行。

容器技術

容器技術等輔助性技術趨勢與微服務同時出現,以幫助人們在微服務器環境中部署服務和應用,從而真正隔離各個業務服務和每個服務的可擴展性。DockercontainedrktKubernetes等容器技術可以作爲微服務開發的很好補充。如今,我們提到微服務或容器其中之一時,肯定就要談到另一種技術了。

單體vs微服務vs無服務器

如前所述,瞭解這三種架構風格的優缺點是很重要的:也就是單體應用、微服務和無服務器函數。一項對比單體與微服務的案例研究報告詳細描述了一個避免使用微服務的場景。

表1重點展示了這三種選項之間的高階差異。

架構風格 何時使用 何時避免使用 使用場景案例
單體 應用程序具有不同的模塊,這些模塊在事務上下文中完全相互依賴。所有數據操作都需要實時一致。 應用程序模塊可以拆分爲原子業務或技術函數。 ERP或CRM系統。
微服務 應用程序模塊在其運行時生命週期和事務管理中彼此獨立。能夠以無狀態方式執行每個模塊中的數據操作。即使模塊之間存在任何依賴關係,它們仍然可以與最終的一致性支持鬆散地結合在一起。 注意:有時,團隊會人爲地將相關函數分解爲微服務,並會遇到微服務模型的侷限性。 如果不嚴格依賴其他模塊,則無法獨立部署和使用應用程序模塊。 客戶支持服務;訂單管理服務;庫存管理服務。
無服務器 具有完全獨立性和單獨可伸縮性策略的應用程序模塊可以分解爲業務或技術的單個函數。 沒有流量時,應用程序將完全關閉。 開發團隊不必關心基礎架構。 長時間運行的作業、CRUD服務或有狀態服務。 驗證;通知;事件流。

表1:服務架構模型以及何時使用或避免使用它們

穩定性鴻溝

我們務必要注意,隨着時間的流逝,我們的軟件架構和代碼中可能會形成很多反模式。反模式不僅會造成技術債務,而且更重要的是它們可能會將主題專家趕出組織。組織最後可能會充斥着那些不關心架構偏差或反模式的員工。

回顧以上簡短的歷史後,我們來重點討論在匆忙推行微服務的過程中可能會出現的穩定性鴻溝和反模式。

諸如組織中的團隊結構、業務領域以及團隊中的技能組等特定因素,決定了哪些應用程序應實現爲微服務,哪些應保留爲單體解決方案。我們選擇將解決方案設計爲微服務時,還可以參考一些一般性的注意事項。

Eric Evans的著作《領域驅動設計(DDD)》改變了我們開發軟件的方式。Eric提出了從領域的角度,而不是從基於技術的角度來審視業務需求的理念。

這本書認爲微服務是聚合模式的一個變體。但是,許多軟件開發團隊會嘗試將其所有現有應用都轉換爲微服務,結果將微服務的設計概念推向了極致。這導致了許多反模式,例如單體地獄、微晶石等。

以下是架構和開發團隊需要注意的一些反模式:

  • 單體地獄
  • 微晶石
  • 積木塔(Jenga tower)
  • 商標幻燈片(也稱爲科學怪人)
  • 方輪(square wheel)
  • 死星

在下一篇文章中,我們將詳細介紹這些反模式。

不斷髮展的架構模式

爲了彌補在不同的應用程序託管模型中發現的衆多穩定性鴻溝和反模式,業界開發出了許多不斷髮展的架構模式和最佳實踐來填補缺陷。

下表總結了這些架構模型、穩定性鴻溝和模式。

託管模型 描述 穩定性鴻溝/反模式 模式
中心化 中央數據存儲和計算模型。客戶終端僅用於數據輸入和數據顯示。
去中心化 客戶端/服務器架構,其中大多數應用程序邏輯在服務端處理。基本驗證和某些處理在客戶端上進行。 意大利麪條代碼,混亂 面向對象編程
連接/共享 Web應用程序通過在Web服務器上託管的表示邏輯(UI)、在應用程序服務器上託管的業務邏輯(API)和數據庫服務器中的數據來形成三層架構。 混亂 領域驅動設計,企業集成模式,SOA
雲託管 雲計算模型改變了託管和擴展應用程序的方式。除了舊的“購買還是構建”選項之外,還爲我們提供了“在雲上託管”的第三個選項。 單體地獄,依賴地獄 微服務
微服務 細粒度的服務模型將特定的業務函數封裝到輕量級應用程序(微服務)中,並在業務領域之間建立清晰的邊界。 單體地獄,微晶石,死星 服務網格,邊車,服務編排
表2:應用程序託管模型、反模式和模式

圖4總結了所有這些架構模型、反模式形式的穩定性鴻溝及不斷髮展的設計模式和最佳實踐。

圖4:架構演變和應用程序託管模型

我們能從歷史中學到什麼

圖5列出了架構演進的步驟,初始階段中人們尚未探索出新範式中的最佳實踐,這會加重技術債務。隨着行業開發出新的設計模式來彌補穩定性鴻溝,團隊開始在其架構中採用新的標準和模式。

圖5:架構模型和新模式的推行

業務與技術

IT領導者必須在不斷髮展和優化的技術基礎上提供穩定業務應用的同時,保護其投資免受無止境的技術快速變革的影響。全球範圍內的IT主管正在越來越頻繁地面對這類問題。

他們和我們都應該擁抱技術的發展,但不應該爲此讓支持業務的應用陷入持續不穩定的狀態。

紀律嚴明的系統架構應該能夠做到這一點。可以將本系列文章中討論的模式看作有利於技術快速發展,並保護業務應用免受變化影響的策略。我們會在下一篇文章中探討如何做到這一點。

總結

從大型機到最新的雲原生架構,各種託管模型都會影響我們開發、部署和維護業務應用的方式。業界每發現一種新的託管模式時,團隊爲了獲取這種架構的全部優勢,都會面臨相應的挑戰。這會導致意想不到的後果,例如架構偏差和反模式,從而帶來了沉重的技術債務。隨着時間的流逝,新的設計模式會不斷涌現,以解決新託管模式所帶來的穩定性問題。

技術債務管理在整個系統以及團隊的健康發展中發揮着至關重要的作用。如果IT管理層不及時處理技術債務,可能會造成與軟件相關的損害,並傷害組織本身。技術債務可以自我增殖,產生更多債務,同時導致不良實踐制度化,還會排擠頂尖人才。

如果出現這些跡象,請立即停止當前的工作並開始評估,然後採取堅定的行動。

你一定要授權團隊解決所有形式的技術債務。

本系列的後續文章將研究我的組織在採用微服務架構期間開發的一個通用服務平臺。我們還將討論公司如何利用不同的雲原生架構組件,如容器、PaaS和服務網格等。

下一篇文章將深入探討團隊應注意的反模式,以及應在架構中採用的雲原生設計模式。我們將討論企業採用雲原生服務網格戰略的細節,這一戰略將助力文中提到的衆多能力。最後,我們將分享一些針對架構和組織的建議。

參考文獻

作者介紹

Srini Penchikala是位於德克薩斯州奧斯汀的通用汽車公司全球製造IT部門的高級IT架構師。他在軟件架構、設計和開發方面擁有超過25年的經驗,目前專注於雲原生架構、微服務和服務網格、雲數據管道以及持續交付領域。Penchikala是在組織中實施企業雲原生服務網格解決方案的共同創建者和首席架構師。Penchikala撰寫了《用Apache Spark處理大數據》一書,並與Manning合著了《Spring Roo in Action》。他經常在各種會議上發表演講,是一位大數據培訓師,並在各種技術網站上發表了多篇文章。

Marcio Esteves是位於得克薩斯州休斯敦的Tokyo Marine HCC的應用開發總監,負責領導解決方案架構、質量保證和開發團隊在公司和企業IT領域協作,推動通用技術的普及,重點工作是在全球範圍內部署基於雲的創收系統。之前,Esteves是通用汽車IT全球製造部的首席架構師和雲原生工程師,負責利用機器學習、大數據、IoT和AI/雲優先微服務架構等技術進行數字轉型。Esteves制定了願景和戰略,並領導了GM的企業雲原生服務網格解決方案的實施,該解決方案具有可自動縮放的微服務,供幾個關鍵業務應用使用。他還擔任奧斯汀市中心VertifyData的董事會技術顧問。

原文鏈接

Adoption of Cloud-Native Architecture, Part 1: Architecture Evolution and Maturity

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章