從分層架構到微服務架構(一)

2021-10-17 07:20:46 字數 4237 閱讀 3645

《從分層架構到微服務架構》是一系列介紹《fundamentals of software architecture》中提到的8種架構模式的文章,這裡不會事無鉅細地介紹所有的細節,而是會挑選其中關鍵內容,更多詳情請閱讀原書。

談到軟體系統設計的方**,在**層面,有我們熟悉的23種設計模式(design pattern),對應到架構層面,則有所謂的架構模式(architecture pattern)。它們分別從微觀和巨集觀的角度指導著我們設計出良好的軟體系統,因此,作為乙個軟體工程師,我們不僅要熟悉設計模式,對常見的架構模式也要熟稔於心。正如看到乙個設計模式的名字腦裡就能浮現出大致的結構圖,當我們看到乙個架構模式的名字時,也要馬上想到對應的架構圖及其基本特點。比如,當談到分層架構時,我們就應該想起它的架構圖是怎樣的、有哪些出色的架構特徵(architecture characteristics)、系統是如何部署的、資料儲存的策略是哪種、等等。

一般地,架構模式大致可以分成兩類,單體架構(monolithic architecture)和分布式架構(distributed architecture)。本系列文章將會介紹以下8種常用的架構模式:

單體架構

分布式架構

在介紹架構模式前,我們先談談軟體設計中的謬誤(fallacy)。所謂謬誤,就是在設計軟體系統,特別是分布式系統時,我們先入為主地假設它們是正確,但實際上並非如此的一些觀念。這些觀念都是我們在設計軟體時考慮不周的體現。

很多軟體工程師常常假設網路是可靠的,但實際並非如此。相比20年前,現在的網路會可靠很多,但是仍然具有很大的不確定性。如上圖所述,serivce b可能完全是正常執行的,但是因為網路的問題,service a發出的請求無法到達service b。一種更糟糕的場景是,service b可以收到service a的請求,並處理了相關的資料,但是網路問題導致了service a無法收到service b的響應,從而造成了資料不一致。網路的不可靠也是為什麼系統中常常出現服務通訊超時、服務熔斷等的原因。

總而言之,如果假設網路是可靠的,那麼我們設計出來的軟體系統將會是不可靠的。

如上圖所示,服務內元件間的函式/方法級別的呼叫,耗時是微妙,甚至是納秒級別;但是服務間的遠端呼叫(比如rest、訊息佇列、rpc),耗時會是微秒級別,甚至在異常場景會達到了秒級!在設計系統,特別是分布式系統時,時延是乙個無法被忽視的因素,我們必須清楚系統的平均時延,否則設計出來的方案可能根本不可行。比如,假設系統中服務間通訊時延為100ms,如果乙個請求的呼叫鏈涉及到10個服務,那麼該請求的時延將會是1000ms!這麼高的平均時延對於一般系統來說是完全無法接受的。

進行系統設計時,考慮平均時延還不夠,更重要的是95th和99th百分點。乙個系統的平均時延可能僅僅只有數十毫秒,但是95th百分點的時延卻達到了數百毫秒,很多時候,這也恰恰成為了拖垮整系統效能的那塊「短板」。

在單體架構中,業務流程都在單服務內閉環,消耗的頻寬很少甚至為0,因此頻寬並不是主要關注點。一旦將系統拆分成分布式架構,乙個業務流程可能涉及多個服務間的通訊,頻寬就成了必須考慮的因素。頻寬的不足,會導致網路變慢,從而影響系統的時延(謬誤2:時延是0)和可靠性(謬誤1:網路是可靠的)

如上圖所示,假設在乙個web系統中,service a負責處理前端請求,service b負責管理使用者資訊(包括姓名、性別、年齡等45個屬性)。service a每處理乙個請求都需要向service b查詢使用者姓名(200 bytes),而在一次請求中,service b卻返回了使用者的所有資訊(500 kb)。如果系統每秒處理2000次請求,每次請求消耗500 kb頻寬,那麼每秒消耗的總頻寬會是1 gb!如果service b僅僅返回必須的姓名,那麼同等條件下,每秒消耗的總頻寬僅僅是400 kb。

vpn、防火牆等的廣泛使用,使得很多任務程師在設計系統時忽略了「網路是不安全的」這一重要原則。特別是從單體架構演進到分布式架構以後,系統被攻擊的概率將會大大增加。因此,在分布式系統中,每個服務都必須是安全的endpoint,這樣才能確保任何未知或惡意的請求都被攔截掉。當然,安全是有代價的,這也是像微服務架構這類細服務粒度的系統,一次業務請求中呼叫鏈過長後效能極速下降的重要原因。

這裡的網路拓撲指的是系統執行時所涉及到的網路裝置,包括所有的路由器、防火牆、集線器、交換機等。很多任務程師會假設網路拓撲是固定的,然而並非如此。

假設如下場景,為架構師的你在周一早上回到公司後,發現組內同事都在為系統中所有的服務間通訊都在不斷出現響應超時現象而抓狂,但奇怪的是週末並沒有做服務變更。經過幾個小時的攻關後,你發現周一凌晨2點時有過一次網路公升級,而恰恰是這次「次要」的網路公升級,推翻之前設計系統時的時延假設,從而觸發了本次事故。

因此,軟體工程師也需要與網路管理員時常聯絡,確保在每次網路公升級前都明確網路拓撲的變更點,從而做出相應的調整

網路管理員往往不止有乙個,特別是在「雲」時代,資料中心分散在多個地域,理所當然也存在著多個區域網。執行在「雲」上的系統很有可能跨越多個資料中心,因此工程師們應當感知各個資料中心的網路管理員對網路的相關操作,提前做出應對措施,避免出現因網路拓撲變更(謬誤5:網路拓撲一成不變)而導致的服務通訊超時,甚至觸發服務熔斷。

這裡的通訊成本並非指網路時延,而是指每增加一次服務間呼叫所導致的的花銷。很多任務程師在設計系統時常常忽視掉通訊成本,大家都在鼓吹分布式架構相對了單體架構的優越性,卻忘記了它帶來的伺服器、防火牆、閘道器等硬體的數量增加,這些都是白花花的銀子。

因此,在進行系統設計時,我們也應該將硬體資源和網路拓撲納入考慮因素。

很多任務程師都會假設網路是同質的,也就是所有的網路裝置都來自同一硬體廠商,這當然也是乙個謬誤。實際上,乙個大的通訊網路中,硬體裝置往往來自於不同的廠商,這得益於網路協議標準的統一。廠商間裝置的協作測試畢竟不會太充分,在一些特殊場景下極有可能存在網路丟包,從而影響了網路的可靠性(謬誤1:網路是可靠的)、時延(謬誤2:時延是0)以及頻寬(謬誤3:頻寬是無限的)。

「大泥球」架構是著名的反模式架構,最初在2023年由brian foote 和 joseph yoder提出。在「大泥球」架構裡,系統沒有進行內部的模組劃分,**耦合嚴重,呼叫關係混亂,就像乙個大的泥球。如上圖所示,每乙個點代表乙個類,紅線則表示類之間的耦合關係。這樣的架構對需求變更極不友好,往往牽一髮而動全身,而且在部署、可測試性、效能等方面也存在著很多問題。所有的架構師都在極力避免「大泥球」的出現,但很不幸的是,它仍然在實際專案中很常見,特別是專案伊始,**質量和結構還沒被嚴格管控起來前。

跟設計模式類似,架構模式是軟體工程師們多年來在架構設計方面的經驗總結。每種架構模式並沒有絕對的優劣之分,我們不能說微服務架構就一定比單體分層架構優越,它們都有著各自的應用場景。分布式架構比單體架構有著更好的可擴充套件性、容錯性,但也帶來了更高的複雜性,比如分布式事務。因此,我們應該熟知各個架構模式的特點,這樣才能在特定的業務場景使用合適的架構模式。

架構模式的演變之路 從單體架構到微服務架構

談到軟體系統設計的方 在 層面,有我們熟悉的23種設計模式 design pattern 對應到架構層面,則有所謂的架構模式 architecture pattern 它們分別從微觀和巨集觀的角度指導著我們設計出良好的軟體系統,因此,作為乙個軟體工程師,我們不僅要熟悉設計模式,對常見的架構模式也要熟...

沉思於軟體架構 從整體到微服務

我最近一直在計畫一些個人專案,而這個主題引起了我的注意。我已經看到了太多關於微服務的炒作,因此我需要將自己的想法放到視野中。我知道微服務是乙個非常有效的架構模型,並且一旦擴充套件就可能是雲軟體開發的必然階段 但是我認為從乙個新專案開始就使用微服務架構風格是乙個壞主意。我看到微服務架構在基礎架構上增加...

軟體架構 微服務架構

我們可以將微服務架構 microservices architecture 理解為 soa 的公升級。基於以下相同點 當問到微服務架構與soa的區別,我們能找到以下回答 微服務其核心思想是在應用開發領域,使用一系列微小服務來實現單個應用的方式途徑,或者說微服務的目的是有效的拆分應用,實現敏捷開發和部...