走進Spring Cloud Alibaba的世界

不撓頭的小王發表於2020-09-24

springcloud-alibaba

在這裡插入圖片描述

Spring Cloud Alibaba 是所有的實現方案中功能最齊全的。尤其是在 Netflix 停止更新了以後,Spring Cloud Alibaba 依然在持續更新和迭代。

理論篇

俗話說,沒有最好的架構,只有最合適的架構。微服務架構也是隨著資訊產業的發展而出現的最有普遍適用性的一套架構模式。通常來說,我們認為架構發展歷史經歷了這樣一個過程:單體架構 -> SOA 面向服務架構 -> 微服務架構

單體架構

在我們還是學生的年代,我們建立的絕大部分應用都屬於單體應用。那個時候,我們幾乎都是一個人在開發導師佈置下來的各種實驗。我們會把資料庫連線、業務邏輯處理、展示邏輯等放在一起,甚至會在處理使用者請求的地方直接連線資料庫(多麼美好的回憶啊 _ )。

後來,我們會學習到MVC架構以及由此衍生出來各種多層架構,由此便開啟了應用的拆分之旅。多層架構的本質,是按照技術職責將應用做水平拆分,每一層解決的技術問題相對集中,層與層之間做單向依賴。這樣做可以幫助我們更好的管理我們的程式碼,大大提升了後期的維護效率。但是,此時應用還是一個應用,部署時也是按照一個整體執行。我們看到的應用架構應該類似下面的樣子:

在這裡插入圖片描述

在程式規模不大,開發人員很少的時候,下面的優點是非常顯著的:

  • 開發簡單。單體應用的結構,天然決定了所有程式碼都集中在一起,開發者不需要在多個應用之間來回跳轉來尋找其中的呼叫邏輯。
  • 測試簡單。所有程式碼都在一個應用裡,測試人員可以很方便的做到端到端的測試(當然,很多時候測試人員就是開發者自己)。
  • 部署簡單。因為一個應用就是產品功能的全集,所以在部署的時候,只需要不是一款應用即可。即使是叢集部署,也不會增加多少複雜度:只需要將應用部署多份即可。
  • 開發迅速。上面的各種簡單,帶來的就是軟體功能可以快速實現。很多時候,實現需求的速度是專案成功與否的決定性因素。

所以,在開發簡單&獨立的產品時,單體架構依然是第一優先選擇。

如果故事可以一直這麼簡單就好了。
隨著功能的持續增加、團隊規模的不斷擴大,我們很快就會發現單體應用的弊端:

  • 應用膨脹。所有程式碼都在一個應用裡,導致應用的程式碼量迅速上升,對於開發者來說,經常需要在海量的程式碼裡找到自己需要維護的哪一行,這種體驗往往是令人崩潰的。同時,對於IDE來說,一個應用內大量程式碼也會嚴重拖慢其執行效率。
  • 團隊合作衝突。這種衝突會體現在多個方面:開發階段,很容易由於修改相同的程式碼導致程式碼衝突。部署階段,又會因為“執行環境裡跑的是誰的分支”而造成新的衝突。所有的這些衝突將會嚴重影響到團隊的合作效率。
  • 執行效率&穩定性。單體應用,由於邏輯都集中在一起,啟動時需要完成所有的初始化工作;同時單一功能的問題也會因為執行在一個程式內,從而導致整個應用當機。

單體架構原有的迅速、簡單的優點,隨著規模的擴大(功能、團隊),會變得蕩然無存。
為了能解決這些問題,我們自然而然就會想到分而治之的辦法,即將原來的單體應用拆分開來。但是應用該怎麼拆分?拆分後又會有哪些新的問題產生?如何解決這些新的問題?就留給下面的 SOA 架構來解答。

SOA 架構

SOA 是 Service-Oriented Architecture 的簡寫,直譯為“面向服務的架構”,從命名上就可以看出“服務”是 SOA 架構裡是非常重要的概念。SOA 的核心思想是“將系統的功能解構為一系列服務”:

面向服務的架構(SOA)是一個元件模型,它將應用程式的不同功能單元(稱為服務)進行拆分,並通過這些服務之間定義良好的介面和協議聯絡起來。介面是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平臺、作業系統和程式語言。這使得構件在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。

與單體架構按照技術職責進行水平拆分不同,SOA 會按照業務領域對應用進行粗粒度的垂直拆分,至於拆分到什麼程度,哪些領域可以放在一起等類似問題,可以參考一下康威定理。

應用從單體應用做了垂直拆分以後,就會變成一些相對獨立的應用。此時,應用間的依賴、呼叫等相關問題自然而然的就會浮現出來。此時就需要下面這些技術方案來解決這些問題:

  • XML - 一種標記語言,用於以文件格式描述訊息中的資料。
  • SOAP(Simple Object Access Protocol) - 在計算機網路上交換基於XML的訊息的協議,通常是用HTTP。
  • WSDL(Web Services Description Language,Web服務描述語言) - 基於XML的描述語言,用於描述與服務互動所需的服務的公共介面,協議繫結,訊息格式。
  • UDDI(Universal Description, Discovery, and Integration,是統一描述、發現和整合) - 基於XML的註冊協議,用於釋出WSDL並允許第三方發現這些服務。
  • ESB(Enterprise Service Bus, 企業服務匯流排)- 支援異構環境中的服務、訊息,以及基於事件的互動,並且具有適當的服務級別和可管理性。

一個典型的 SOA 架構模式如下圖:

在這裡插入圖片描述

SOA 看似解決了單體架構的所有問題,世界似乎都變得更加美好了 _

但是….

SOA 並不完美,他也有很多問題的或者說是場景下的不適應。首先就是對 SOA 的解釋缺乏統一標準,上文的引用的定義也只是眾多解釋中使用的較為通用的一種。甚至可以這麼說:一千個人眼中,有一千種 SOA 。基於此,很多廠商便借用 SOA 的大旗來推廣自己的產品和標準,這又進一步加劇了問題的嚴重性。

除此之外,SOA 還有很多其他的問題或不足:

  • 高門檻。ESB 本身就是一套非常複雜的系統,通過 ESB 落地 SOA ,對開發人員的要求很高。甚至還會需要廠商參與;
  • 廠商繫結。由於缺乏統一保準,不同廠商的解決方案之間很難做切換。
  • 不適應雲環境。在如今的網際網路時代,速度就是一切。由此誕生了敏捷開發、持續整合等在不同節點提升業務上線速度的辦法。但是方向是不一致的。
  • 中心化。雖然應用本身實現了分散式與水平擴充套件,但是 ESB 卻成了系統的中樞神經。

微服務架構

對於微服務架構,一直有一種說法,認為它是SOA架構的一種變體,或者是SOA的子集。關於這個問題,我們不去討論他的對錯(其實也沒有對錯之分),我們直接從這兩者的區別入手來理解到底什麼是微服務:

傳統SOA微服務
通訊方式基於ESB,SOAP、WSDL等重協議點對點通訊,開放式協議,如 RESTful、gRPC、或者是輕量級的二進位制協議。
資料管理全域性資料模型以及共享儲存每個服務獨立模型和儲存
服務粒度較粗較細
誕生的背景企業級應用網際網路
解決的問題面向企業內,系統整合面向最終產品,解決擴充套件,維護的問題

通訊手段、資料等的不同只是表象,其本質區別還是由於兩者誕生於不同歷史時期,需要解決的問題域不同。SOA 解決的核心問題是複用,而微服務解決的核心問題是擴充套件。

這個定義對微服務做了一個比較具象化較為易於理解的描述,通常來說我們看到的為服務架構如下圖所示:

在這裡插入圖片描述

但是事實上,在實際生產環境中,微服務的架構要考慮的問題遠比上面的示意圖複雜的多,主要包括但不限於如下問題:
- 通過服務實現元件化
- 根據業務組織系統
- 做產品而不是做專案
- 簡單高效的通訊協議
- 自動化基礎設施
- 面向失敗的設計
- 具備進化能力的設計

今天我們所說的“微服務”是一個龐大且複雜的概念集合,它既是一種架構模式,也是實現這種架構模式時所使用的技術方案的集合。

“微服務”不是銀彈
微服務並不是一勞永逸的解決了所有的問題,相反的,如果不能正確的使用微服務,則有可能被微服務自身的限制拖入另一個泥潭:
- 分散式的代價。原本在單體應用中,很多簡單的問題都會在分散式環境下被幾何級的放大。例如分散式事務、分散式鎖、遠端呼叫等,不光要考慮如何實現他們,相關場景的異常處理也是必須要考慮到的問題。
- 協同代價。如果你經歷過一個專案上線需要釋出十幾個應用,而這些應用又分別由多個團隊在維護。你就能深刻的體會到協同是一件多麼痛苦的事情了。
- 服務拆分需要很強的設計功力。微服務的各種優勢,其中一個重要的基礎是對服務領域的正確切分。如果使用了不合適的切分粒度,或者是錯誤的切分方法,都會讓服務不能很好的實現高內聚低耦合的要求。

框架篇

從 Spring 到 Spring Cloud

Spring

熟悉 java 語言的同學,對 Spring 框架應該都不陌生。從 2004 年 1.0 版本釋出開始,便由於其靈活易用的特性受到了整個 Java 行業的廣泛關注。經過十多年的發展,Spring 框架早已經成為 Java 語言下程式設計模型的事實標準。其所倡導的 IOC/AOP 概念也早已深入人心。

在 Spring 框架的早期,大家都喜歡稱其為“輕量化”框架(現在好像早就沒人提這個詞了_),“輕量”是相對於 EJB 等企業級開發框架而言的。其“輕”的特性體現在:框架本身的大小很小,早期版本的jar包不超過1MB;同時不依賴於執行容器,也是說任何容器裡都可以執行Spring框架;更加重要的是 Spring 是非侵入的,使用Spring開發的應用可以不完全依賴Spring的類;

Spring Boot

但是事情總會發生變化,隨著 Spring 的不斷髮展,越來越多的元件被整合到了框架中。Spring 框架也從一個小巧精簡的 IOC 容器框架變成了一套大而全的框架集合。開發者為了實現元件的整合工作,往往需要在大量的 xml 檔案、java 註解 中完成各種 bean 的配置。曾經屠龍的少年,如今也變成了惡龍。

那個時候,很多比 Spring 更加簡單小巧的 IOC 容器如雨後春筍般的出現。業界開始出現一種聲音:Spring 是不是已經不行了,或者是在走下坡路了。就在這個時候 Pivotal 推出了 Spring Boot 來徹底的解決這些問題。

使用 Spring Boot 可以大大簡化 Spring 應用的開發工作。在 Spring Boot 中無論是官方元件還是第三方框架都會提供各種“starter”來方便開發者進行依賴和整合。由於採用了“約定大於配置”的思想,開發者在引入“stater”以後只需要做少量的配置工作就可以完成框架整合工作。往往開發者只需要很少量的程式碼就可以實現以前大量配置檔案才能做到的功能。

同時 Spring Boot 還是一套面向生產環境設計的框架。配置外化、執行情況檢查功能,可以很方便的在系統外部實現對系統的管理。同時 Spring Boot 還是一個執行時容器。通過內嵌 Tomcat 、Jetty 等使得程式的執行不在依賴傳統的應用伺服器。這一點在雲原生時代意義尤其重大。

Spring 官方對 Spring Boot 特色定義如下:
- 建立獨立的Spring應用程式
- 直接嵌入Tomcat,Jetty或Undertow(無需部署WAR檔案)
- 提供自以為是的“starter”依賴項,以簡化構建配置
- 儘可能自動配置Spring和三方類庫
- 提供可用於生產的功能,例如指標,執行狀況檢查和外部化配置
- 完全沒有程式碼生成,也不需要XML配置

Spring Cloud

Spring Cloud 是什麼,沒有比官方的定義更能說明問題了:

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.

這裡面提到幾個關鍵詞:
- 分散式系統中的常見模式
- 任何分散式環境

“分散式系統中的常見模式”給了 Spring Cloud 一個清晰的定位,即“模式”。也就是說 Spring Cloud 是針對分散式系統開發所做的通用抽象,是標準模式的實現。

這個定義非常抽象,看完之後並不能知道 Spring Cloud 具體包含什麼功能。再來看一下 Spring 官方給出的一個 High Light 的架構圖,就可以對這套模式有更清晰的認識:

在這裡插入圖片描述

可以看到這個圖中間就是各個Microservice,也就是我們的這個微服務的實現,周邊周圍的話就是去圍繞這個微服務來去做各種輔助的資訊事情。例如分散式追蹤、服務註冊、配置服務等,都繞微服務執行時所依賴的必不可少的的支援性功能。我們可以得出這樣一個結論:Spring Cloud 是以微服務為核心的分散式系統的一個構建標準。

Spring Cloud Alibaba

在這裡插入圖片描述

開源部分
- Sentinel:把流量作為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
- Nacos:一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。
- RocketMQ:一款開源的分散式訊息系統,基於高可用分散式叢集技術,提供低延時的、高可靠的訊息釋出與訂閱服務。
- Dubbo:Apache Dubbo? 是一款高效能 Java RPC 框架。
- Seata:阿里巴巴開源產品,一個易於使用的高效能微服務分散式事務解決方案。

相關文章