1. 程式人生 > >Spring Cloud都做了些什麼

Spring Cloud都做了些什麼

Spring Cloud 作為一套微服務治理的框架,幾乎考慮到了微服務治理的方方面面,之前也寫過一些關於 Spring Cloud 的文章,主要偏重各元件的使用。

本次分享主要解答這兩個問題:Spring Cloud 在微服務的架構中都做了哪些事情?Spring Cloud 提供的這些功能對微服務的架構提供了怎樣的便利?

我們先來簡單回顧一下,我們以往網際網路架構的發展情況:

傳統架構發展史

單體架構

單體架構在小微企業比較常見,典型代表就是一個應用、一個數據庫、一個 Web 容器就可以跑起來,比如我們開發的開源軟體雲收藏,就是標準的單體架構。

在兩種情況下可能會選擇單體架構:

  • 在企業發展的初期,為了保證快速上線,採用此種方案較為簡單靈活。

  • 傳統企業中垂直度較高,訪問壓力較小的業務。在這種模式下對技術要求較低,方便各層次開發人員接手,也能滿足客戶需求。

下面是單體架構的架構圖:

在單體架構中,技術選型非常靈活,優先滿足快速上線的要求,也便於快速跟進市場。

垂直架構

在單體架構發展一段時間後,公司的業務模式得到了認可,交易量也慢慢的大起來,這時候有些企業為了應對更大的流量,就會對原有的業務進行拆分,比如說:後臺系統、前端系統、交易系統等。

在這一階段往往會將系統分為不同的層級,每個層級有對應的職責,UI 層負責和使用者進行互動、業務邏輯層負責具體的業務功能、資料庫層負責和上層進行資料交換和儲存。

下面是垂直架構的架構圖:

在這個階段 SSH(Struts+Spring+Hibernate)是專案的關鍵技術,Struts 負責 Web 層邏輯控制、Spring 負責業務層管理 Bean、Hibernate 負責對資料庫操作進行封裝,持久化資料。

服務化架構

如果公司進一步的做大,垂直子系統會變的越來越多,系統和系統之間的呼叫關係呈指數上升的趨勢。

在這樣的背景下,很多公司都會考慮服務的 SOA 化。SOA 代表面向服務的架構,將應用程式按照不同的職責劃分為不同的模組,不同的模組直接通過特定的協議和介面進行互動。

這樣將整個系統切分成很多單個元件服務來完成請求,當流量過大時通過水平擴充套件相應的元件來支撐,所有的元件通過互動來滿足整體的業務需求。

SOA 服務化的優點是,它可以根據需求通過網路對鬆散耦合的粗粒度應用元件進行分散式部署、組合和使用。

服務層是 SOA 的基礎,可以直接被應用呼叫,從而有效控制系統中與軟體代理互動的人為依賴性。

服務化架構是一套鬆耦合的架構,服務的拆分原則是服務內部高內聚,服務之間低耦合。

下面是服務化架構圖:

在這個階段可以使用 Web Service 或者 Dubbo 來服務治理。

SOA 和微服務架構

SOA 和微服務的區別

服務化架構已經可以解決大部分企業的需求了,那麼我們為什麼要研究微服務呢?

先說說它們的區別,如下幾點:

  • 微服務架構強調業務系統需要徹底的元件化和服務化,一個元件就是一個產品,可以獨立對外提供服務。

  • 微服務不再強調傳統 SOA 架構裡面比較重的 ESB 企業服務匯流排。

  • 微服務強調每個微服務都有自己獨立的執行空間,包括資料庫資源。

  • 微服務架構本身來源於網際網路的思路,因此元件對外發布的服務強調了採用 HTTP Rest API 的方式來進行。

  • 微服務的切分粒度會更小。

總結:微服務架構是 SOA 架構思想的一種擴充套件,更加強調服務個體的獨立性、拆分粒度更小。

為什麼考慮 Spring Cloud

考慮 Spring Cloud 的原因有如下幾點:

  • Spring Cloud 來源於 Spring,質量、穩定性、持續性都可以得到保證。

  • Spirng Cloud 天然支援 Spring Boot,更加便於業務落地。

  • Spring Cloud 發展非常的快,從 2016 年開始接觸的時候相關元件版本為 1.x,到現在將要釋出 2.x 系列。

  • Spring Cloud 是 Java 領域最適合做微服務的框架。

  • 相比於其它框架,Spring Cloud 對微服務周邊環境的支援力度最大。

  • 對於中小企業來講,使用門檻較低。

  • Spring Cloud 是微服務架構的最佳落地方案。

Spring Cloud 的特性

以下為 Spring Cloud 的核心特性:

  • 分散式/版本化配置。

  • 服務註冊和發現。

  • 路由。

  • 服務和服務之間的呼叫。

  • 負載均衡。

  • 斷路器。

  • 分散式訊息傳遞。

這些特性都是由不同的元件來完成,在架構的演進過程中扮演著重要的角色,接下來我們一起看看。

微服務架構

Spring Cloud 解決的第一個問題就是:服務與服務之間的解耦。很多公司在業務高速發展的時候,服務元件也會相應的不斷增加。

服務和服務之間有著複雜的相互呼叫關係,經常有服務 A 呼叫服務 B,服務 B 呼叫服務 C 和服務 D …,隨著服務化元件的不斷增多,服務之間的呼叫關係成指數級別的增長,極端情況如下圖所示:

這樣最容易導致的情況就是牽一髮而動全身,經常出現由於某個服務更新而沒有通知到其它服務,導致上線後慘案頻發。

這時候就應該進行服務治理,將服務之間的直接依賴轉化為服務對服務中心的依賴。Spring Cloud 核心元件 Eureka 就可以解決這類問題。

Eureka

Eureka 是 Netflix 開源的一款提供服務註冊和發現的產品,它提供了完整的 Service Registry 和 Service Discovery 實現。它也是 Spring Cloud 體系中最重要最核心的元件之一。

用大白話講,Eureka 就是一個服務中心,將所有的可以提供的服務都註冊到它這裡來管理,其他各呼叫者需要的時候去註冊中心獲取,然後再進行呼叫,避免了服務之間的直接呼叫,方便後續的水平擴充套件、故障轉移等。如下圖:

當然服務中心這麼重要的元件一旦掛掉將會影響全部服務,因此需要搭建 Eureka 叢集來保持高可用性,生產中建議最少兩臺。

隨著系統的流量不斷增加,需要根據情況來擴充套件某個服務,Eureka 內部已經提供均衡負載的功能,只需要增加相應的服務端例項既可。

那麼在系統的執行期間某個例項掛了怎麼辦?Eureka 內容有一個心跳檢測機制,如果某個例項在規定的時間內沒有進行通訊則會自動被剔除掉,避免了某個例項掛掉而影響服務。

因此使用了 Eureka 就自動具有了註冊中心、負載均衡、故障轉移的功能。

Hystrix

在微服務架構中通常會有多個服務層呼叫,基礎服務的故障可能會導致級聯故障,進而造成整個系統不可用的情況,這種現象被稱為服務雪崩效應。

服務雪崩效應是一種因“服務提供者”的不可用導致“服務消費者”的不可用,並將不可用逐漸放大的過程。

如下圖所示:A 作為服務提供者,B 為 A 的服務消費者,C 和 D 是 B 的服務消費者。A 不可用引起了 B 的不可用,並將不可用像滾雪球一樣放大到 C 和 D 時,雪崩效應就形成了。

在這種情況下就需要整個服務機構具有故障隔離的功能,避免某一個服務掛掉影響全域性。在 Spring Cloud 中 Hystrix 元件就扮演這個角色。

Hystrix 會在某個服務連續呼叫N次不響應的情況下,立即通知呼叫端呼叫失敗,避免呼叫端持續等待而影響了整體服務。Hystrix 間隔時間會再次檢查此服務,如果服務恢復將繼續提供服務。

Hystrix Dashboard 和 Turbine

當熔斷髮生的時候需要迅速的響應來解決問題,避免故障進一步擴散,那麼對熔斷的監控就變得非常重要。

熔斷的監控現在有兩款工具:Hystrix-dashboard 和 Turbine。

Hystrix-dashboard 是一款針對 Hystrix 進行實時監控的工具,通過 Hystrix Dashboard 我們可以直觀地看到各 Hystrix Command 的請求響應時間, 請求成功率等資料。

但是隻使用 Hystrix Dashboard 的話, 你只能看到單個應用內的服務資訊, 這明顯不夠。

我們需要一個工具能讓我們彙總系統內多個服務的資料並顯示到 Hystrix Dashboard 上,這個工具就是 Turbine。

監控的效果圖如下:

配置中心

隨著微服務不斷的增多,每個微服務都有自己對應的配置檔案。在研發過程中有測試環境、UAT 環境、生產環境,因此每個微服務又對應至少三個不同環境的配置檔案。

這麼多的配置檔案,如果需要修改某個公共服務的配置資訊,如:快取、資料庫等,難免會產生混亂,這個時候就需要引入 Spring Cloud 另外一個元件:Spring Cloud Config。

Spring Cloud Config

Spring Cloud Config 是一個解決分散式系統的配置管理方案。它包含了 Client 和 Server 兩個部分,Server 提供配置檔案的儲存、以介面的形式將配置檔案的內容提供出去,Client 通過介面獲取資料、並依據此資料初始化自己的應用。

具體實現是 Server 端將所有的配置檔案服務化,需要配置檔案的服務例項去 Config Server 獲取對應的資料。將所有的配置檔案統一整理,避免了配置檔案碎片化。

如果服務執行期間改變配置檔案,服務是不會得到最新的配置資訊,需要解決這個問題就需要引入 Refresh。它可以在服務的執行期間重新載入配置檔案。

當所有的配置檔案都儲存在配置中心的時候,配置中心就成為了一個非常重要的元件。

如果配置中心出現問題將會導致災難性的後果,因此在生產中建議對配置中心做叢集,來支援配置中心高可用性。

Spring Cloud Bus

上面的 Refresh 方案雖然可以解決單個微服務執行期間過載配置資訊的問題,但是在真正的實踐生產中,可能會有 N 多的服務需要更新配置。

如果每次依靠手動 Refresh 將是一個巨大的工作量,這時候 Spring Cloud 提出了另外一個解決方案:Spring Cloud Bus。

Spring Cloud Bus 通過輕量訊息代理連線各個分佈的節點。這會用在廣播狀態的變化(例如配置變化)或者其它的訊息指令中。

Spring Cloud Bus 的一個核心思想是通過分散式的啟動器對 Spring Boot 應用進行擴充套件,也可以用來建立一個或多個應用之間的通訊頻道。目前唯一實現的方式是用 AMQP 訊息代理作為通道。

Spring Cloud Bus 是輕量級的通訊元件,也可以用在其它類似的場景中。有了 Spring Cloud Bus 之後,當我們改變配置檔案提交到版本庫中時,會自動的觸發對應例項的Refresh,具體的工作流程如下:

服務閘道器

在微服務架構模式下,後端服務的例項數一般是動態的,對於客戶端而言很難發現動態改變的服務例項的訪問地址資訊。

因此在基於微服務的專案中為了簡化前端的呼叫邏輯,通常會引入 API Gateway 作為輕量級閘道器,同時 API Gateway 中也會實現相關的認證邏輯從而簡化內部服務之間相互呼叫的複雜度。

Spring Cloud 體系中支援 API Gateway 落地的技術就是 Zuul。Spring Cloud Zuul 路由是微服務架構中不可或缺的一部分,提供動態路由,監控,彈性,安全等的邊緣服務。

Zuul 是 Netflix 出品的一個基於 JVM 路由和服務端的負載均衡器。

它的具體作用就是服務轉發,接收並轉發所有內外部的客戶端呼叫。使用 Zuul 可以作為資源的統一訪問入口,同時也可以在閘道器做一些許可權校驗等類似的功能。

鏈路跟蹤

隨著服務數量越來越多,對呼叫鏈的分析會越來越複雜,如服務之間的呼叫關係、某個請求對應的呼叫鏈、呼叫之間消費的時間等,對這些資訊進行監控就成為一個問題。

在實際的使用中,我們需要監控服務和服務之間通訊的各項指標,這些資料將是我們改進系統架構的主要依據。

因此分散式的鏈路跟蹤就變的非常重要,Spring Cloud 也給出了具體的解決方案:Spring Cloud Sleuth 和 Zipkin。

Spring Cloud Sleuth 為服務之間呼叫提供鏈路追蹤。通過 Sleuth 可以很清楚的瞭解到一個服務請求經過了哪些服務,每個服務處理花費了多長時間。從而讓我們可以很方便的理清各微服務間的呼叫關係。

Zipkin 是 Twitter 的一個開源專案,允許開發者收集 Twitter 各個服務上的監控資料,並提供查詢介面。

總結

我們從整體上來看一下 Spring Cloud 各個元件如何來配套使用。

從上圖可以看出 Spring Cloud 各個元件相互配合,合作支援了一套完整的微服務架構:

  • Eureka 負責服務的註冊與發現,很好地將各服務連線起來。

  • Hystrix 負責監控服務之間的呼叫情況,連續多次失敗進行熔斷保護。

  • Hystrix dashboard,Turbine 負責監控 Hystrix 的熔斷情況,並給予圖形化的展示。

  • Spring Cloud Config 提供了統一的配置中心服務。

  • 當配置檔案發生變化的時候,Spring Cloud Bus 負責通知各服務去獲取最新的配置資訊。

  • 所有對外的請求和服務,我們都通過Zuul來進行轉發,起到 API 閘道器的作用。

  • 最後我們使用 Sleuth+Zipkin 將所有的請求資料記錄下來,方便我們進行後續分析。

Spring Cloud 從設計之初就考慮了絕大多數網際網路公司架構演化所需的功能,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等。

這些功能都是以插拔的形式提供出來,方便我們系統架構在演進的過程中,可以合理的選擇需要的元件進行整合,從而在架構演進的過程中會更加平滑、順利。

微服務架構是一種趨勢,Spring Cloud 提供了標準化的、全站式的技術方案,意義可能會堪比當前 Servlet 規範的誕生,有效推進服務端軟體系統技術水平的進步。