Spring Cloud 中的分散式組件五花八門,我到底該怎麼學?

来源:https://www.cnblogs.com/javastack/archive/2023/10/12/17759577.html
-Advertisement-
Play Games

分散式架構的演進 在軟體行業,一個應用服務隨著功能越來越複雜,用戶量越來越大,尤其是互聯網行業流量爆髮式的增長,導致我們需要不斷的重構應用的結構來支撐龐大的用戶量,最終從一個簡單的系統主鍵演變成了一個非常複雜的可以支撐高併發的高可用的分散式架構,但是一個系統再複雜也是不斷演變來的,所以從另一方面來說 ...


分散式架構的演進

在軟體行業,一個應用服務隨著功能越來越複雜,用戶量越來越大,尤其是互聯網行業流量爆髮式的增長,導致我們需要不斷的重構應用的結構來支撐龐大的用戶量,最終從一個簡單的系統主鍵演變成了一個非常複雜的可以支撐高併發的高可用的分散式架構,但是一個系統再複雜也是不斷演變來的,所以從另一方面來說,其實是業務(問題)推動了技術的發展。

傳統的單體應用

在早期,我們開發的都是單體應用,也就是一個系統所有的模塊都在一個服務上:

這種傳統的應用開發和運維都非常簡單,隨著用戶量的增加,我們發現應用程式的壓力越來越大,於是我們會選擇對應用進行集群部署:

當然因為選擇了集群,我們就需要考慮服務分發的問題,所以需要有負載均衡伺服器,比如我們最常用的 nginx,還有 lvs,HaProxy 等,硬體層面也可以選擇 F5 來實現負載均衡等等。

當然,在使用了集群之後,我們還需要考慮 session 共用的問題,所以相比較單機架構會稍微複雜一點點,那麼到這裡我們應用進行了擴展了,這時候發現資料庫又到瓶頸了,所以資料庫又需要進行擴展。

資料庫的擴展可以有兩種主流方式:

讀寫分離

通過讀寫分離以及在某些場景用分散式存儲系統替換關係型資料庫的方式,能夠降低主庫的壓力,解決數據存儲方面的問題,不過隨著業務的發展,主庫依然會遇到瓶頸。

分庫分表

當採用讀寫分離之後,如果再次遇到瓶頸,那麼就可以採用垂直拆分的方式來實現,垂直拆分的意思是把資料庫中不同的業務數據拆分到不同的資料庫中。但是這樣有些熱門模塊依然遲早會遇到瓶頸,於是可以更進一步採用水平拆分,水平拆分就是把同一個表的數據拆分到不同的資料庫中。

垂直拆分還比較容易處理,畢竟同一個模塊的數據還是在一起,水平拆分就會比較複雜了,比如說用戶表拆成了兩張,存在不同的資料庫中,那麼存的時候到底該存的哪個庫,取的時候又該到哪個庫去查詢,所以水平拆分需要考慮以下問題:

  • 插入和查詢的路由問題,需要根據某一個條件來決定當前數據應該分到哪個庫。
  • 主鍵的處理,主鍵不能採用自增主鍵的形式,因為不同的庫採用自增主鍵會有衝突。
  • 如果某些查詢需要到兩個庫去查詢,會比較難處理。

資料庫的拆分可以使用當前比較流行的 Sharding JDBC 或者 MyCat 來實現,這時候的架構大致就會如下圖所示:

當然,為了進一步優化,可以視情況加入緩存層,或者使用消息隊列等技術來削峰等優化措施。

分散式架構

分散式架構是指位於網路電腦上的各個組件(系統)僅通過傳遞消息來通信和協調目標系統,分散式系統其實也可以認為是一種去中心化的實現思路,對於用戶來說是無感知的。

分散式架構的意義

從單機單用戶到單機多用戶,再到現在的網路時代,應用系統發生了很多的變化,為什麼單體架構會逐漸滿足不了需求轉而要採用分散式架構呢?

原因主要有以下幾點:

  • 升級單機處理能力的性價比越來越低。
  • 單機處理能力存在瓶頸,一臺伺服器的處理能力始終是會有上限的。
  • 對於穩定性和可用性的要求,單機環境下無法提供,一旦單機應用掛了,整個系統就全部掛了,而分散式架構則不會存在這個問題,某一個模塊不可用並不會導致整個系統的不可用。

SOA 架構

SOA 全稱為 Service Oriented Architecture,即面向服務架構。SOA 是一種架構理念。它的提出主要是解決服務之間的耦合問題。

SOA 對服務之間的解耦是一種比較粗粒度的劃分,比如我們的電商網站按服務可以拆分為:用戶模塊,訂單模塊,商品模塊等。SOA 其本質上是服務的集合,然後服務間一般會通過 ESB 匯流排來進行通信。比如之前比較常用的 webservice 就是一種 SOA 架構的實現。

微服務架構

微服務架構在 SOA 架構的基礎上做了進一步的細化,微服務架構和 SOA 架構並沒有本質上的區別,都是為了服務的解耦,只不過微服務架構更加關註服務的粒度,比如上面提到的用戶模塊我們還可以進一步拆分成更細粒度的服務。

隨著微服務架構的普及,原本一個單體應用可能會被拆分成幾十個甚至更多的服務,從應用的壓力上來說,我們把壓力進行了分流,但是原本一個服務變成了多個服務對開發者和運維者來說也帶來了極大的挑戰,這也就隨之衍生了一些技術組件,比如服務與與服務之間如何通信?單個服務如果是集群如何實現負載均衡?配置如何進行統一管理?適合實現分流?如何實現監控等。

註冊中心

各個微服務相互之間需要進行調用,那麼服務與服務之間又是如何知道對方的調用信息(如 ip,埠,路由等),最簡單最直接的辦法就是每個服務都維護一個其他需要調用的服務地址信息,但是這樣會給開發和運維帶來相當大的工作量,當我們有某一個服務 A 的地址信息發生變更,那麼只要調用了 A 服務的其他所有服務都要隨之修改。而且假如 A 服務宕機了,其他服務也無法發現,當然,也可以做大發現,但是這會相當麻煩,而且每個服務都要重覆實現這個功能,這會導致非常繁瑣和重覆的工作,所以微服務常用組件中就有了註冊中心。

註冊中心是微服務架構中一個核心的基礎服務,主要用來管理所有的微服務,並且註冊中心需要實現服務上線和下線的感知。

也就是說我們所有的微服務都將自己的地址信息註冊到註冊中心,然後其他調用者只需要維護註冊中心的地址即可,當一個服務下線的時候,註冊中心也會及時將該服務剔除。

常用的註冊中心有:Eureka,consul,Nacos,其他的還有 Zookeeper,Redis 等也可以實現註冊中心。

遠程通信協議

微服務之間各個服務可能會非常頻繁的調用,所以我們一定需要一款高效便捷的通訊協議來完成遠程通信。

為什麼使用 rpc 而不直接使用 http

回答這個問題之前我們先來回答另一個問題,微服務之間能不能直接使用 http 來進行通信?答案是肯定的,但是直接使用 http 來作為遠程通信會有以下問題:

  • 請求和返回參數需要自己封裝,過程比較繁瑣。
  • http 協議是基於 tcp 協議實現的,每次連接和斷開需要三次握手和四次揮手,這過程會帶來一定的網路開銷。

基於上面兩個問題,我們需要另一種更加高效便捷的通信方式來完成微服務之間的通信,這就是 rpc 通信。

RPC(Remote Procedure Call)遠程過程調用,它是一種通過網路從遠程電腦程式上請求服務,而不需要瞭解底層網路技術的協議,達到調用遠程服務就像調用本地方法一樣,也就是調用者並不知道這個方法會具體去調用哪個服務。

不過需要強調的是 RPC 並不是一種協議,這一點和 http 是有本質區別的,rpc 只是一種技術名詞,其底層實現也可以使用 http 協議,也可以基於 tcp 協議自己去進行改造。

RPC 主要是用來解決兩個問題:

  • 處理分散式架構中各個微服務之間的通訊問題。
  • 遠程調用時,調用者就像調用本地方法一樣方便。

常用的分散式服務之間遠程通訊組件有:feign,openfeign,dubbo 等。

負載均衡

提到負載均衡大家的第一反應就是 nginx,一般我們使用 http 通訊時大部分都會使用 nginx 作為負載均衡來處理,那麼我們的微服務能否直接使用 nginx 來進行負載呢?

答案是可以的,但是我們為什麼不直接使用 nginx 作為服務轉發呢?我個人覺得主要有以下三個考慮:

  • nginx 主要是一款基於 http 來進行的 七層負載(當然其也能實現四層負載),而我們的微服務通信之間不一定會基於 http 協議。
  • 如果使用了 nginx,等於是微服務之間又多引入了一個單點,我們還需要考慮 nginx 轉發的問題,還需要對其進行配置調優等。
  • 微服務使用了註冊中心來進行統一管理服務的上線和下線,而如果使用 nginx 那麼就需要使用 openresty 結合 lua 腳本才能實現從註冊中心獲取服務。

也就是說直接使用 nginx 來進行負載的話,技術上是可行的,但是卻可能會引入一些新的問題,所以微服務之間的負載均衡並沒有直接選擇使用 nginx,而是重新開發了負載均衡組件。

常用的分散式服務之間負載均衡組件有:ribbon 等。

配置中心

假如我們某一個模塊部署了幾十甚至上百個集群部署,那麼如果每個服務都單獨使用自己的配置文件的話,一旦修改某一個配置,那麼我們需要同時修改即使甚至上百個服務的配置,這是一個苦力活,所以我們就需要考慮讓這些服務共用同一套配置,這樣只要修改這一套配置,所有服務都能能生效。

配置中心主要就是用來解決這個問題,為瞭解決這個問題,配置中心需要具備以下能力:

  • 提供配置文件的管理界面(dashboard),這樣使用者可以直接通過訪問 dashboard 來實現可視化配置。
  • 配置中心配置修改之後,需要能及時通知到對應服務,讓對應服務修改最新配置。

常用的分散式服務之間負載均衡組件有:apollo,nacos,Spring Cloud config,disconf,diamond,Zookeeper 等。

服務降級/熔斷

引入微服務我們的目的就是為了讓每一個微服務都成為一個獨立的單元,我們可以對每一個服務進行獨立擴展,實現高可用,假如現在有一個服務 A 因為一下子併發量過高導致請求堆積,那麼就會造成越來越多的請求阻塞,最終造成雪崩效應導致服務 A 宕機,最終可能會導致整個微服務架構不可用,所以為了保證高可用用,微服務需要提供一種降級和熔斷措施。

降級也可以分為主動降級和被動降級,主動降級就是在高峰期比如我關閉一些非核心功能,如:評論,留言等功能。

而熔斷一般指的是某一個方法或者介面負載過高,或者說因為網路都動等原因造成響應超時或者失敗等,那麼這時候應該主動觸發熔斷,也就是對後續請求不再處理而是直接返回,當然這也要視具體業務來決定採用何種熔斷措施。

常用的分散式服務之間降級/熔斷組件有:Hystrix 和 Sentinel 等。

服務網關

微服務架構是由單體服務架構發展而來,一般我們一個一個微服務架構其實是一個大的應用系統,那麼必然這一個大的系統有公共部分,比如:統一授權,統一路由,統一記錄日誌,也可以進行全局的限流措施等。

不過微服務網關並不是必須的,這些工作也可以放到每個服務中進行處理。

常用的微服務網關組件有:Zuul,Spring Cloud GatWay。

這麼多分散式組件該如何選擇

分散式架構中主要有六大組件,而每個組件又有不同的實現,看起來技術五花八門,感覺需要學的東西非常多,但是上面介紹了這麼多分散式組件。

其實其主要就是三大類型:Spring Cloud NetflixSpring Cloud 官方Spring Cloud Alibaba,下麵我們對這些分散式組件進行歸納分類,這樣大家在學習的時候就可以進行有目的的針對性學習:

Spring Cloud Netflix 是由 Netflix(美國奈飛)公司開源的一套分散式組件,這套組件應該也是大家比較熟悉的一套分散式組件,不過其只有 1.0 版本開源,2.0 之後就不再開源了,Spring Cloud 官方自己也提供了部分組件,而且基於 Feign 的基礎上改造成了 Open Feign。

另外一套比較完整的分散式組件就是 Spring Cloud Alibaba,這是由阿裡巴巴開源的的一套分散式組件,這套組件中的 dubbo 大家應該也是比較熟悉的,除了這兩套組件外,其他的也有一些可以用來作為分散式組件,比如 Zookeeper,Consul 等,配置中心像 apollo 是攜程開源的,用的也比較多,所以大家學習的時候可以對同類組件進行瞭解,並對比其特性,然後選擇一套適合自己系統的組件使用。

除了上面的六大分散式組件外,分散式架構中還會涉及到另外兩個比較大的問題:

分散式消息

分散式消息一般就使用消息隊列,比如 Rabbit MQ,Rocket MQ(阿裡巴巴體系),kafka 等。

分散式事務

分散式事務的話,Spring Cloud Alibaba 也提供了一個組件 seata 來實現。

另外分散式系統當中還涉及到鏈路監控相關問題,這方面可以選擇 sleuth + zipkin,pinponit,skywalking等等。所以說分散式架構解決了單體架構一些問題的同時,也帶來了一些問題,但是技術總是在向前發展的,比如現在號稱為了微服務而生的 Kubernetes(k8s),又有號稱是下一代微服務架構的 Service Mesh等。

一門技術的誕生總是為瞭解決一些問題,所以還是那句話:業務才是推動技術發展的根本原因。 只有隨著業務的發展出現了問題,才會去解決問題,才有更好的促進新技術的誕生。

比如現在流行的 docker,也是為瞭解決微服務過多導致部署困難問題,任何一門技術能得到發展,它一定是解決了當前的痛點,否則我們為什麼要使用它?假如互聯網沒有興起,併發量始終很低,那麼微服務也不會興起,直接使用傳統的單點應用反而更簡單直接。

總結

本文主要講述了從單點應用到分散式架構的發展歷程,並且描述了微服務當中為什麼會誕生出一批組件,其根本原因就是為瞭解決微服務所帶來的的挑戰和問題,在文中最後對當前流行的分散式架構組件進行了分類整理,幫助大家梳理思路,這樣就可以做到有目的的進行針對性的學習,希望通過本文能讓大家對微服務相關組件有一個清晰的學習思路。

原文鏈接:https://blog.csdn.net/zwx900102/article/details/121727985
版權聲明:本文為CSDN博主「雙子孤狼」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


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

-Advertisement-
Play Games
更多相關文章
  • 在日常生活和工作中,我們經常需要處理海量的數據,篩選出有用的信息。這個時候,布隆過濾器(Bloom Filter)就派上了用場 ...
  • 最近很多小伙伴說,不會用瀏覽器開發者工具,今天我們就一起來深入瞭解一下開發者工具。 以谷歌瀏覽器為例 谷歌瀏覽器開發者工具中的Network 是我們學習經常用到的,那麼你都知道他們每個功能的意義嗎? 因本人經常有360極速瀏覽器,谷歌內核,所以本文以360極速瀏覽器的開發者工具Network為例,基 ...
  • 本方法適用於Linux環境下: 1.安裝庫Cython pip3 install Cython==3.0.0a10 2.編寫待加密文件:hello.py import random def ac(): i = random.randint(0, 5) if i > 2: print('success ...
  • 在Redis和MySQL的實際應用過程中,如何保證Redis和MySQL雙寫時的數據一致性問題成為了開發者們面臨的重要挑戰 ...
  • 本文已收錄至GitHub,推薦閱讀 👉 Java隨想錄 微信公眾號:Java隨想錄 原創不易,註重版權。轉載請註明原作者和原文鏈接 目錄Pipeline介紹原生批命令(MSET, MGET) VS PipelinePipeline的優缺點一些疑問Pipeline代碼實現 當我們談論Redis數據處 ...
  • 基於java醫院管理系統設計與實現,可適用於醫院信息管理系統,醫院掛號系統,醫院醫生排班系統,醫院患者管理系統,醫院醫生預約系統,醫院預約系統,醫院藥物信息系統,醫院預約掛號系統,醫療管理系統,醫療系統等等; ...
  • 除了Vue 3這個庫,還需Vue 3 最新全家桶。 1 環境準備 之前語法演示直接使用script引入Vue 3,從而在瀏覽器里實現所有調試功能。但實際項目中,使用專門調試工具。在項目上線之前,代碼也需打包壓縮,並考慮到研發效率和代碼可維護性,所以在下麵,需建立一個工程化項目實現這些功能。 工具 V ...
  • 出於安全的考慮,瀏覽器會禁止 Ajax 訪問不同域的地址,在現如今微服務橫行的年代,跨域訪問是非常常見的。W3C 的 CORS (Cross-origin-resource-sharing) 規範中也已經允許跨域訪問, 並被主流瀏覽器所支持,它們包括: Chrome 3+; Firefox 3.5+ ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...