微服務1:微服務及其演進史

翁智華發表於2021-12-16

1 傳統單體系統介紹

在很多專案的業務初期階段,高速迭代上線是首要考慮的事情,對後期的容量預估、可擴充套件性和系統健壯性、高可用一般沒有那麼重視。但隨著業務的發展,使用者量、請求量的暴增,

發現原來的單體系統已經遠遠不滿足需求了,特別是隨著網際網路整體的高速發展,對系統的要求越來越高。

但是物理伺服器的CPU、記憶體、儲存器、連線數等資源有限,單體系統能夠承受的的QPS也是有限的,某個時段大量連線同時執行操作,會導致web服務和資料庫服務在處理上遇到效能瓶頸。

為了解決這個問題,偉大的前輩們發揚了分而治之的思想,對大資料庫、大表進行分割,可以參考我的《分庫分表》,以便實施更好的控制和管理。

同時建立多個服務例項,使用多臺服務機進行CPU、記憶體、儲存的分攤,提供更好的效能。

 

1.1 單體系統的問題

1、複雜性高:由於是一個單體的系統,所以整個系統的模組是耦合在一起的,模組的邊界比較模糊、依賴關係錯綜複雜。功能的調整,容易帶來不可知的影響和潛在的bug風險。

2、服務效能問題:單體系統遇到效能瓶頸問題,只能橫向擴充套件,增加服務例項,進行負載均衡分擔壓力。無法縱向擴充套件,做模組拆分

3、擴縮容能力受限:單體應用只能作為一個整體進行擴充套件,影響範圍大,無法根據業務模組的需要進行單個模組的伸縮

4、無法做故障隔離:當所有的業務功能模組都聚集在一個程式集當中,如果其中的某一個小的功能模組出現問題(如某個請求堵塞),那麼都有可能會造成整個系統的崩潰

5、釋出的影響範圍較大:每次釋出都是整個系統進行釋出,釋出會導致整個系統的重啟,對於大型的綜合系統挑戰比較大,如果將各個模組拆分,哪個部分做了修改,只發布哪個部分所在的模組即可

 

1.2 單體系統的優點

1、系統的簡易性:系統語言風格、業務結構,介面格式均具有一致性,服務都是耦合在一起的,不存在各個業務通訊問題。

2、易於測試:單體應用一旦部署,所有的服務或特性就都可以使用了,簡化了測試過程,無需額外測試服務間的依賴,測試均可在部署完成後開始。

3、易於部署與升級:相對於微服務架構中的每個服務獨立部署,單體系統只需將單個目錄下的服務程式統一部署和升級。 

4、較低的維護成本:只需維護單個系統即可。運維主要包括配置、部署、監控與告警和日誌收集四大方面。相對於單體系統,微服務架構中的每個服務都需要獨立地配置、部署、監控和日誌收集,成本呈指數級增長

 

1.3 單體服務到微服務的發展過程

EUREKA的註冊中心逐漸被ZooKeeper和Nacos等替代了。

 

2 關於微服務

微服務是一種架構模式,是面向服務的體系結構(SOA)軟體架構模式的一種演變,
它提倡將單一應用程式劃分成一組鬆散耦合的細粒度小型服務,輔助輕量級的協議,互相協調、互相配合,為使用者提供最終價值。
所以,微服務(或微服務架構)是一種雲原生架構方法,其中單個應用程式由許多鬆散耦合且可獨立部署的較小元件或服務組成。這些服務通常包含如下特點: 

2.1 單一職責

微服務架構中的每個節點高度服務化,都是具有業務邏輯的,符合高內聚、低耦合原則以及單一職責原則的單元,包括資料庫和資料模型;
不同的服務通過“管道”的方式靈活組合,從而構建出龐大的系統。

2.2 輕量級通訊

通過REST API模式或者RPC框架,實現服務間互相協作的輕量級通訊機制。

2.3 獨立性

在微服務架構中,每個服務都是獨立的業務單元,與其他服務高度解耦,只需要改變當前服務本身,就可以完成獨立的開發、測試、部署、運維

2.4 程式隔離

在微服務架構中,應用程式由多個服務組成,每個服務都是高度自治的獨立業務實體,可以執行在獨立的程式中,不同的服務能非常容易地部署到不同的主機上,實現高度自治和高度隔離
程式的隔離,還能保證服務達到動態擴縮容的能力,業務高峰期自動增加服務資源以提升併發能力,業務低谷期則可自動釋放服務資源以節省開銷。 

2.5 混合技術棧和混合部署方式

團隊可以為不同的服務元件使用不同的技術棧和不同的部署方式(公有云、私有云、混合雲)。

2.6 簡化治理

元件可以彼此獨立地進行擴縮容和治理,從而減少了因必須縮放整個應用程式而產生的浪費和成本,因為單個功能可能面臨過多的負載。 

2.7 安全可靠,可維護。

從架構上對運維提供友好的支撐,在安全、可維護的基礎上規範化釋出流程,支援資料儲存容災、業務模組隔離、訪問許可權控制、編碼安全檢測等。 

3 微服務演進史 

我們前面已經瞭解了微服務的概念,通過百度指數可以看出,從2012年之後,微服務的發展有顯著的發展趨勢

 

目前業內的微服務相關開發平臺和框架還是比較多的,比如較早的Spring Cloud(使用Eureke做服務註冊與發現,Ribbon做服務間負載均衡,Hystrix做服務容錯保護),

阿里的Dubbo,微軟的.Net體系微服務框架 Service Fabric,再到後來進階的服務網格(Service Mesh,如 Istio、Linkerd)。

那從12年開始到現在,微服務到底發展到哪個階段了,在各個階段的進階過程中,又有哪些的變化。所以我們需要了解微服務技術的歷史發展脈絡。

下面的內容參考了 Phil Calçado的文章《Pattern: Service Mesh》,從開發者的視角,詳細分析了從微服務到Service Mesh技術的演進過程這邊做了進一步的整理和總結。 

3.1 第一階:簡單服務通訊模組

這是最初的模樣,開發人員最開始的時候想象的兩個服務間簡單的通訊模式,抽象表示如下,兩個服務之間直接進行通訊:

   

3.2 第二階:原始通訊時代

上面的方式非常簡單,但實際情況遠比想象的複雜很多,通訊需要底層位元組碼傳輸和電子訊號的物理層來完成,在TCP協議出現之前,

服務需要自己處理網路通訊所面臨的丟包、錯誤、亂序、重試等一系列流控問題,因此服務實現中,除了業務邏輯外,還包含對網路傳輸問題的處理邏輯

 

3.3 第三階:TCP時代

TCP協議的出現,避免了每個服務自己實現一套相似的網路傳輸處理邏輯,解決網路傳輸中通用的流量控制問題。

這時候我們把處理網路傳輸的能力下沉,從服務的實現中抽離出來,成為作業系統網路層的一部分。

 

3.4 第四階:第一代微服務(Spring Cloud/RPC)

TCP出現之後,服務間的網路通訊已經不是一個難題了,所以 GFS/BigTable/MapReduce 為代表的分散式系統得到了蓬勃的發展。

這時,分散式系統特有的通訊語義又出現了,如服務註冊與發現、負載均衡、熔斷降級策略、認證和授權、端到端trace、日誌與監控等,因此根據業務需求,完成一些通訊語義的實現。

  

3.5 第五階:第二代微服務

為了避免每個服務都需要自己實現一套分散式系統通訊的語義功能,隨著技術的發展,一些面向微服務架構的通用開發框架出現了,如Twitter的Finagle、Facebook的Proxygen以及Spring Cloud等,

這些框架實現了分散式系統通訊需要的各種通用語義功能:如負載均衡和服務發現等,因此一定程度上遮蔽了這些通訊細節,使得開發人員使用較少的框架程式碼就能開發出健壯的分散式系統。

  

3.6 第六階:第一代Service Mesh

上面的第二代微服務框架目前看著挺完美了,但整套微服務框架其實是很複雜的,比如Spring Cloud,聚合了很多元件。所以在實踐過程中,會發現有如下諸多問題:

  • 侵入性強。想要整合SDK的能力,除了需要新增相關依賴,業務層中入侵的程式碼、註解、配置,與治理層界限不清晰。
  • 升級成本高。每次升級都需要業務應用修改SDK版本,重新進行功能迴歸測試,並對每一臺服務進行部署上線,與快速迭代開發相悖。
  • 版本碎片化嚴重。由於升級成本高,而中介軟體版本更新快,導致線上不同服務引用的SDK版本不統一、能力參差不齊,造成很難統一治理。
  • 中介軟體演變困難。由於版本碎片化嚴重,導致中介軟體向前演進的過程中就需要在程式碼中相容各種各樣的老版本邏輯,帶著"枷鎖”前行,無法實現快速迭代。
  • 內容多、門檻高。依賴元件多,學習成本高,即使通用分散式系統遮蔽了很多的實現細節,我們引入微服務框架並熟練使用也是要花費巨大的精力的。
  • 治理功能不全。不同於RPC框架,SpringCloud作為治理全家桶的典型,也不是萬能的,諸如協議轉換支援、多重授權機制、動態請求路由、故障注入、灰度釋出等高階功能並沒有覆蓋到。
  • 無法實現真正意義上的語言無關性。提供的框架一般只支援一種或幾種語言,要將框架不支援的語言研發的服務也納入微服務架構中,是比較有難度的。

所以,第一代微服務架構 Service Mesh就產生了,它作為一個基礎設施層,能夠業務解耦,主要解決複雜網路拓撲下微服務與微服務之間的通訊,其實現形態一般為輕量級網路代理,並與應用以邊車代理(SideCar)模式部署,同時對業務應用透明

 

 

SideCar將分散式服務的通訊抽象為單獨一層,需要和服務部署在一起,接管服務的流量,通過代理之間的通訊間接完成服務之間的通訊請求。

所以在這一層中它能夠實現負載均衡、服務發現、認證授權、監控追蹤、流量控制等分散式系統所需要的功能。

 

如果我們從一個全域性視角來,綠色的為應用服務,藍色的為SideCar,就會得到如下部署圖

 

如果我們省略去服務,只看Service Mesh的代理邊車的網格應該是這樣的:

 

流量經過的時候,會先被代理邊車所劫持,然後再進入服務,所以它就是一個由若干服務代理所組成的錯綜複雜的網格。  

3.7 第七階:第二代Service Mesh

第一代Service Mesh由一系列獨立執行的單機代理服務構成,為了提供統一的上層運維入口,演化出了集中式的控制皮膚,我們稱之為控制面(control plane)

控制面和所有的資料面(data plane,即代理邊車)進行互動,比如策略下發、資料採集等。這就是以Istio為代表的第二代Service Mesh。

 

只包含控制面和資料面的 Service Mesh 服務網格全域性結構圖 如下:

 

從上面的結構圖可以看出,Service Mesh 的基礎設施層主要分為兩部分:控制平面與資料平面。當前流行的開源服務網格 Istio 和 Linkerd 都是這種構造。

控制平面的特點:

  • 不直接解析資料包。
  • 與控制平面中的代理通訊,下發策略和配置。
  • 負責網路行為的視覺化。
  • 通常提供 API 或者命令列工具可用於配置版本化管理,便於持續整合和部署。

資料平面的特點:

  • 通常是按照無狀態目標設計的,但實際上為了提高流量轉發效能,需要快取一些資料,因此無狀態也是有爭議的。
  • 直接處理入站和出站資料包,轉發、路由、健康檢查、負載均衡、認證、鑑權、產生監控資料等。
  • 對應用來說透明,即可以做到無感知部署。

到這一步我們大概瞭解了微服務架構的演進過程,也初步瞭解Service Mesh技術比較於傳統的微服務架構有哪些優勢。

相關文章