《一遍文章讓你看懂的SpringCloud、錯過你會後悔》


目前公司使用的 Spring Cloud 整個技術組件,基本包含了上面圖中所包含的,不得不說,Spring Cloud 整個生態真的很強大,使用起來也很方便有效。算法

後面有時間再針對每一個組件進行使用解讀,這篇文章主要說下 Spring Cloud 架構的鏈路圖,順便把本身的思路整理下來,以備查閱。數據庫

閱讀目錄:後端

  • 1、 網關請求流程
  • 2、Eureka 服務治理
  • 3、 Config 配置中心
  • 4、 Hystrix 監控
  • 5、服務調用鏈路
  • 6、ELK 日誌鏈路
  • 7、統一格式返回


1、 網關請求流程bash


在 Spring Cloud 整個組件庫中,Spring Cloud Zuul 是最容易被忽視,但也是最重要的,Spring Cloud Zuul 能夠和 Eureka 註冊中心集成,咱們目前使用 Spring Cloud Zuul 的功能以下:服務器

  • Filter 過濾器
  • Router 路由
  • Ribbon 負載均衡
  • Hystrix 熔斷
  • Retry 重試

有些功能是 Spring Cloud Zuul 自帶的,好比 Filter 和 Router,有些是結合 Spring Cloud 其餘組件,好比 Ribbon 和 Hystrix。架構

這裏重點介紹下 Filter 過濾器,分爲四個過濾類型:app

  • pre :Zuul 轉發請求以前執行,咱們目前的實現是 AccessTokenFilter ,用於 oAuth2.0 JWT 的受權驗證。
  • route :Zuul 路由時執行,目前項目沒用到。
  • post :Zuul 路由轉發後執行,也就是已經請求成功了後端服務,咱們目前的實現是 CustomResponseFilter ,用於統一請求格式的封裝,好比 code/msg/data 等。
  • error :以上過濾器發生錯誤時執行,咱們目前的實現是 CustomErrorFilter ,用於攔截過濾器執行的出現的錯誤,而後統一格式封裝返回,另外,error 過濾器好像並不能捕獲後端服務執行出現的錯誤。

另外,關於 oAuth2.0 JWT 的受權驗證,實現的方式有兩種:負載均衡

AccessTokenFilter
複製代碼

咱們目前採用的是第二種方式,這兩種方式都有利有弊,關鍵在於本身的取捨,爲何採用第二種方式?目的就是發揮 Zuul 的做用,對外網關進行統一受權驗證。curl

關於受權 Map,裏面存儲了全部服務接口的配置,示例配置:分佈式


這是咱們目前的配置,是一個靜態的 Map,後面會存儲在 Spring Cloud Config 配置中心,Zuul 啓動時進行加載,利用 Spring Cloud Bus 動態刷新。

關於 Zuul 網關,其實還有不少須要說的,後面有機會再進行鍼對說明。

2、 Eureka 服務治理


Eureka 遵循的是 AP 原則(服務可用性和分區容錯性),是服務治理最理想的遵循 CAP 分佈式原則。

Eureka 集羣中的節點是彼此平級,不像 Consul 有 master/worker 之分,集羣中的 Eureka 節點彼此兩兩註冊,因此,Eureka 集羣最好部署三個節點,這也是咱們目前的部署方式。

服務之間的相互調用,負載有兩種使用方式:

  • Feign :基於聲明式,顧名思義,就是須要定義接口,就像咱們日常使用對象調用同樣。
  • Ribbon :軟負載,經過往 RestTemplate 中注入負載 Handler,而後經過負載算法選取調用(經過 Eureka 獲取服務註冊信息)。

咱們目前打算使用 Ribbon 負載方式,爲何?看下面代碼就知道了:


3、 Config 配置中心


咱們目前配置中心使用的是 Spring Cloud Config,固然你也可使用功能更強大的 Polly(攜程開源),但 Config 目前也能知足咱們的需求,存儲倉庫咱們如今使用的是 Git。

Config 配置中心提供了數據加密功能,你可使用 RSA 的加密方式,這樣存儲在 Git 中的配置都是密文形式,Config Client 獲取加密配置的時候,Config Server 會自動進行解密返回。

配置中心的使用場景,咱們目前主要是兩個地方:

  • 項目啓動的配置信息,好比數據庫的鏈接字符串等。
  • 業務服務的配置信息,也就是業務相關的配置。

另外,須要說明的是,默認狀況下,若是 Git 中的配置更新了,Config Client 不會進行更新配置,咱們目前的解決方式是,使用 Spring Cloud Bus 進行動態刷新配置(Config Server 中配置),具體的流程:

curl -X POST http://manager1:8180/bus/refresh
複製代碼

4、Hystrix 監控


Hystrix 主要是用於服務熔斷/降級/隔離處理,Hystrix 配置在調用方,當被調用方服務不可用時,觸發 Hystrix 熔斷,會執行指定的 Fallback 方法,進行特殊處理。

我以前覺得,Hystrix 熔斷的觸發條件是服務不可用,也就是服務請求超時(好比服務掛掉了),但我本身測試了下,服務出現 500 錯誤,也會觸發 Hystrix 熔斷,並且會自動忽略 Hystrix 的超時時間設置。

咱們目前使用 Hystrix,主要有兩個地方:

  • 內部服務調用 :能夠對某個 API 接口進行熔斷處理。
  • Zuul 網關使用 :就是當 Zuul 路由轉發調用時,但有個侷限性,就是隻能對服務進行熔斷,並不能針對某個 API 接口熔斷。

上面圖中,主要畫的是 Hystrix 的監控流程,咱們目前主要使用 RabbitMQ 進行採集傳輸,turbine-server 進行數據流的聚合,hystrix-dashboard 進行圖形化的展現。

5、 服務調用鏈路


服務調用鏈路的概念,就是當服務請求發起時,記錄整個請求鏈路的數據,以備查詢。

目前市面上,幾乎全部服務調用鏈路的實現,理論基礎都是基於 Google Dapper 的那篇論文,其中最重要的概念就是 traceId 和 spanId。

  • traceId 記錄整個服務鏈路的 ID,由首次請求方建立,服務鏈路中惟一。
  • spanId 記錄當前服務塊的 ID,由當前服務方建立。
  • parentId 記錄上一個請求服務的 spanId。

下面我描述下,咱們目前的服務調用鏈路過程:

  • H5 發起請求,到 Zuul 網關,Zuul 建立全局的 traceId 和本身的 spanId,而後攜帶這些數據到業務服務 A,並利用 Spring Cloud Sluth 傳輸到 RabbitMQ。
  • 業務服務 A,接收到 Zuul 傳輸的 traceId 和 spanId,而後把 Zuul 的 spanId 設置成 parentId,並生成本身的 spanId,而後攜帶這些數據到業務服務 B,並利用 Spring Cloud Sluth 傳輸到 RabbitMQ。
  • ....

上面圖中,詳細說明了整個服務調用鏈路的過程,這邊再說下使用的技術棧:

  • Spring Cloud Sluth:和 SkyWalking 的探針概念比較相似,每一個服務都進行配置,收集固然服務的請求數據(traceId 和 spanId),而後利用 stream-sluth 和 binder-rabbit 組件,將請求數據傳輸到 RabbitMQ。
  • Spring Cloud Zipkin:主要用於請求鏈路的 UI 展現,Zipkin 會從 RabbitMQ 讀取請求數據,而後存儲到 ElasticSearch 中,而後下次顯示直接從 ElasticSearch 中讀取。
  • Kibana:Kibana 也能夠顯示 ElasticSearch 中的請求數據,只不過不是圖形化的,須要索引配置建立。

6、ELK 日誌鏈路


上面圖中已經很詳細介紹了下 ELK 的流程,ELK 默認技術棧裏是沒有 Filebeat 的,Logstash 用做日誌收集的時候,CPU 和內存會佔用資源比較大,因此咱們使用輕量化的 Filebeat 進行日誌的收集,Filebeat 部署在每一個業務服務所在的服務器,而後將收集到的日誌數據傳輸到 Logstash,Logstash 能夠部署兩到三臺服務器上,用做日誌的過濾和分析工做,而後再將處理後的日誌數據,傳輸到 ElasticSearch 存儲。

7、統一格式返回

這是我本身在工做對SpringCloud,但願對你們有所幫助一塊兒共同成長進步

相關文章
相關標籤/搜索