Spring Cloud 微服務架構全鏈路實踐

来源:https://www.cnblogs.com/xishuai/archive/2018/07/05/spring-cloud-microservice.html
-Advertisement-
Play Games

閱讀目錄: 1. 網關請求流程 2. Eureka 服務治理 3. Config 配置中心 4. Hystrix 監控 5. 服務調用鏈路 6. ELK 日誌鏈路 7. 統一格式返回 "Java 微服務框架選型(Dubbo 和 Spring Cloud?)" 目前公司使用的 Spring Cloud ...


閱讀目錄:

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

Java 微服務框架選型(Dubbo 和 Spring Cloud?)

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

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

1. 網關請求流程

在 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 過濾器,分為四個過濾類型:

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

另外,關於 oAuth2.0 JWT 的授權驗證,實現的方式有兩種:

  • 授權的配置在後端服務中(每個服務都需要當作 Resource Server 進行配置,需要配置公鑰,介面的授權具體配置在註解中),Zuul 只做轉發,並不進行授權的驗證。
  • 授權的配置在 Zuul 中,也就是把 Zuul 當作 Resource Server,後端服務不需要進行任何處理,Zuul 中具體的實現就是AccessTokenFilter,裡面的邏輯是手動解析 JWT,然後判斷是否正確,以及解析出用戶信息/Scope/Role,然後根據當前的請求 API,對授權 Map 中的配置進行匹配,如果匹配錯誤,直接拋出 401 授權錯誤。

我們目前採用的是第二種方式,這兩種方式都有利有弊,關鍵在於自己的取捨,為什麼採用第二種方式?目的就是發揮 Zuul 的作用,對外網關進行統一授權驗證。

關於授權 Map,裡面存儲了所有服務介面的配置,示例配置:

private static final Map ROUTE_MAPS;
static
{
    ROUTE_MAPS = new HashMap<String, String>();
    ROUTE_MAPS.put("eureka-client/home", "read:ROLE_ADMIN");
    ROUTE_MAPS.put("eureka-client/user", "read:ROLE_ADMIN");
    ROUTE_MAPS.put("eureka-client/error", "read:ROLE_ADMIN");
}

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

關於 Zuul 網關,其實還有很多需要說的,後面有機會再進行針對說明。

2. Eureka 服務治理

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

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

另外,Eureka 的自我保護機制,可以參考這篇文章

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

  • Feign:基於聲明式,顧名思義,就是需要定義介面,就像我們平常使用對象調用一樣。
  • Ribbon:軟負載,通過往 RestTemplate 中註入負載 Handler,然後通過負載演算法選取調用(通過 Eureka 獲取服務註冊信息)。

我們目前打算使用 Ribbon 負載方式,為什麼?看下麵代碼就知道了:

restTemplate.getForObject("http://eureka-client/hello", String.class);

3. Config 配置中心

我們目前配置中心使用的是 Spring Cloud Config,當然你也可以使用功能更強大的 Polly(攜程開源),但 Config 目前也能滿足我們的需求,存儲倉庫我們現在使用的是 Git。

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

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

  • 項目啟動的配置信息,比如資料庫的連接字元串等。
  • 業務服務的配置信息,也就是業務相關的配置。

另外,需要說明的是,預設情況下,如果 Git 中的配置更新了,Config Client 不會進行更新配置,我們目前的解決方式是,使用 Spring Cloud Bus 進行動態刷新配置(Config Server 中配置),具體的流程:

  • Git 中添加 WebHooks 腳本,比如curl -X POST http://manager1:8180/bus/refresh,當 Git 倉庫中的配置更新後,自動執行。
  • Config Server 中配置 Spring Cloud Bus,接受 Git 的配置刷新請求,然後利用 RabbitMQ 廣播通知所有的 Config Client 訂閱方,刷新配置信息。

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-sluthbinder-rabbit組件,將請求數據傳輸到 RabbitMQ。
  • Spring Cloud Zipkin:主要用於請求鏈路的 UI 展示,Zipkin 會從 RabbitMQ 讀取請求數據,然後存儲到 ElasticSearch 中,然後下次顯示直接從 ElasticSearch 中讀取。
  • Kibana:Kibana 也可以顯示 ElasticSearch 中的請求數據,只不過不是圖形化的,需要索引配置創建。

6. ELK 日誌鏈路

ELK 可以參考下之前的幾篇文章:

上面圖中已經很詳細介紹了下 ELK 的流程,ELK 預設技術棧里是沒有 Filebeat 的,Logstash 用作日誌收集的時候,CPU 和記憶體會占用資源比較大,所以我們使用輕量化的 Filebeat 進行日誌的收集,Filebeat 部署在每個業務服務所在的伺服器,然後將收集到的日誌數據傳輸到 Logstash,Logstash 可以部署兩到三台伺服器上,用作日誌的過濾和分析工作,然後再將處理後的日誌數據,傳輸到 ElasticSearch 存儲。

7. 統一格式返回

關於統一格式返回,圖中已經詳細的說明瞭,如果你有更好的方案,歡迎探討。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、先上官方文檔 https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-preprocessor-sass-less-etc 二、 ...
  • 前言 很久以前學習《Javascript語言精粹》時,寫過一個關於js的系列學習筆記。 最近又跟別人講什麼原型和繼承什麼的,發現這些記憶有些模糊了,然後回頭看自己這篇文章,覺得幾年前的學習筆記真是簡陋。 所以在這裡將這篇繼承重新更新一下,並且加上ES6的部分,以便下次又對這些記憶模糊了,能憑藉這篇文 ...
  • 可以用 beforeRouteLeave 和 updated 來判斷。export default { ...
  • 入門設計模式之單例 註意一下文章都伴有UML圖,不瞭解的同學請先參考一下:這個幾分鐘幾張圖教你學會如何使用UML 入門設計模式之建造者 入門設計模式之原型 入門設計模式之工廠 入門設計模式之觀察者 入門設計模式之模板 入門設計模式之策略 入門設計模式之橋梁 入門設計模式之外觀 入門設計模式之享元 入 ...
  • Spring框架是一個為java應用程式的開發提供了綜合,廣泛的基礎性支持的java平臺。Spring幫助開發者解決了開發中基礎性的問題,使得開發人員可以專註於應用程式的開發。Spring框架本身亦是按照設計模式精心打造,這時的我們可以在開發環境中安心得集成spring框架,不必擔心Spring是如 ...
  • 第一部,創建報表結構 首先添加數據集項 添加完成之後我們會看到這個頁面 之後我們在上面添加一些數據集 數據源的連接要自己設定 之後我們可以輸入要編譯的sql語句,因為是報表,主要用來查詢,一般情況只用select語句就可以 生成之後是這樣的一些模型 中間的灰色部分可以雙擊,進去之後我們能自定義編寫一 ...
  • 學習更多設計模式請參考:入門設計模式之彙總篇 狀態模式:允許一個對象在其內部狀態改變時改變其行為。 舉一個簡單的小例子,我們在對一個小姐姐搭訕的時候,根據小姐姐的心情如何我們可能會得到不同的回覆。 看一下類圖 看一下代碼: 如此,Boy持有不同狀態的Girl對象時獲取的回覆是不同的,這樣就實現了一個 ...
  • 一、String類 想要瞭解一個類,最好的辦法就是看這個類的實現源代碼,來看一下String類的源碼: public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...