目錄
- 前言
- 閱讀對象
- 閱讀導航
- 前置知識
- 筆記正文
- 一、單體服務介紹
- 二、服務拆分
- 三、分布式微服務升級前的思考
- 3.1 關于SpringBoot/SpringCloud的思考【有點門檻】
- 四、SpringCloud升級整合
- 4.1 新建父子項目
- 學習總結
- 感謝
前言
從本節課開始,我將自己手寫一個基于SpringCloud框架的web服務集群,中間會引入常用的微服務中間件。如:配置中心、網關、鏈路追蹤、斷路器等等。
本節課只是簡單地從原有單體項目,然后升級成SpringCloud架構。
閱讀對象
- 需要有實際Springboot-web開發經驗
閱讀導航
系列上一篇文章:《【分布式微服務專題】微服務架構演進》
系列下一篇文章:《[【分布式微服務專題】【微服務專題】從單體到分布式(一、SpringCloud整合Nacos)(整理中…)]》
前置知識
筆記正文
一、單體服務介紹
為了升級演示效果,我寫了一個簡單的SpringBoot單體應用,架構如下:
然后實現的功能也很簡單,直接list
獲取庫里面所有的數據。主要如下:
1)會員管理模塊:提供一個/user/list
接口,獲取數據庫里面所有用戶數據
2)錢包管理模塊:提供一個/wallet/list
接口,獲取數據庫里面所有錢包數據
3)商品管理模塊:提供一個/product/list
接口,獲取數據庫里面所有商品數據
整體代碼比較簡單,就不貼了。我們前面有說過單體服務的缺點和限制,這邊重申一下:
1)修改任意代碼,甚至是application.yml
都要重新打包編譯部署,重啟服務
2)單體機器存在性能瓶頸
3)很多時候,不同的服務QPS可能不一樣,所以水平拓展的時候粒度不夠精細
第三點對沒有經驗的小白可能理解上有點困難。簡單說就是:在電商系統里面,正常來說訪問商品模塊的人,會比訪問會員模塊的人多。然后服務的性能瓶頸可能往往就是QPS最高的那個模塊引起的,此時需要水平拓展服務,但由于是單體,所以每次拓展,都是對整個系統的拓展。但最理想的效果應該是,只對QPS最高的商品模塊拓展
二、服務拆分
服務拆分之后,其實就可以理解為這就是所謂的【微服務】概念了。微服務簡單說:一個 springboot 就是一個 微服務,并且這個 springboot 做的事情遵循單一職責。 比如說,在這里,服務經過拆分之后架構圖成為了這樣:(我新拓展了一個【訂單服務】,雖然上面沒貼,但是不妨礙理解)
甚至,經過水平拓展,也就是我們說的集群化之后,還可能是這樣:
不過,隨著服務的拆分,有一些衍生問題,卻又無法避免。如下:
- 如何確定那些服務彼此之間的調用鏈路
比如上述架構圖,可能存在會員服務調用訂單服務的情況,那訂單服務有兩個服務,我怎么知道具體調用的是
9081
還是9082
呢。甚至我的會員服務可能也有多臺機器,那勢必存在笛卡爾積的情況,他們之間的鏈路可能會更為復雜
- 同一組服務之間,甚至所有微服務之間,如何共享配置信息,配置如何自動刷新
比如說我多個微服務之間使用的是同一個數據庫,redis,mq,這些配置信息理論上是可以共享的,而不必在每一個應用的
application.yml
文件上都聲明
- 集群有新的服務上線,或者下線,如何處理
服務注冊與發現
- 微服務如何不暴露細節,以一個整體去提供服務
網關
- 分布式事務
- 等等…(有一些我自己也不清楚,學習中)
三、分布式微服務升級前的思考
3.1 關于SpringBoot/SpringCloud的思考【有點門檻】
不知道你們是否跟我一樣有同樣的疑問,即:
- 什么是SpringBoot,如何新建一個SpringBoot項目
- 什么是SpringCloud,如何新建一個SpringCloud項目
- SpringCloudAlibaba和SpringCloud有什么關系
說來屬實慚愧,我在此之前,真的沒有很清晰的認知。只記得他們分別是Spring
腳手架、微服務
腳手架。但是我在做項目升級的時候發現,如果我的認知還是停留在這樣片面的層次,會給我帶來些不小的阻礙。
問題1:什么是SpringBoot,如何新建一個SpringBoot項目
不知道你們是否也一樣,每次新建SpringBoot項目我都得重新百度一下如何新建,或者說,使用Idea的Spring Initializer
來新建,不然對如何從空白項目新建一個SpringBoot沒啥概念。經過這兩天的學習之后,我終于是有點理解了。
簡而言之,創建一個SpringBoot項目大概有如下三種方式:
- 新建一個繼承自
spring-boot-starter-parent
的項目。如下:(這里分享一個相關知識點的傳送門:《理解spring-boot-starter-parent》,大家伙學習下)
spring-boot-starter-parent
主要是為我們使用、構建SpringBoot項目,提供了一些默認的配置。包括:
- 定義了Java編譯版本為1.8。
- 使用UTF-8格式編碼。
- 繼承自spring-boot-dependencies,這個里邊定義了Java+Spring開發常用依賴的版本,也正是因為繼承了這個依賴,所以我們在寫依賴時才不需要寫版本號
- 預定義了一些Maven執行打包操作的配置
- 自動化的資源過濾。
- 自動化的插件配置。
- 針對application.properties和application.yml的資源過濾,包括通過profile定義的不同環境的配置文件,例如applicationdev.properties和application-dev.yml。
使用spring-boot-starter-parent作為父項目,子項目可以繼承父項目的依賴項、插件配置和默認設置,從而簡化子項目的配置和管理。子項目可以通過在其pom.xml文件中引用父項目來繼承這些配置,例如通過元素指定父項目的坐標。將相關的模塊組織成多模塊項目,可以提高代碼的可維護性、復用性和團隊協作效率。同時,使用父項目和子項目的結構,還可以方便地進行整體構建、測試和部署,保證模塊之間的一致性和協調性。
- 新建一個項目,在
<dependencyManagement>
中添加spring-boot-dependencies
的依賴
Spring Boot中的spring-boot-dependencies是一個特殊的依賴項,它提供了一組預定義的版本控制,用于管理Spring Boot及其相關庫的版本。
在Spring Boot項目中,spring-boot-dependencies依賴是一個非常重要的依賴項,它主要作用是統一管理Spring Boot及其相關庫的版本,避免版本沖突,簡化依賴項管理。通過引入spring-boot-dependencies,你可以確保所使用的Spring Boot及其相關庫的版本始終兼容,并能夠輕松地升級到新的版本。
具體來說,spring-boot-dependencies包含了一個BOM(Bill of Materials)文件,這是一個包含了一系列庫的清單,指定了這些庫的版本號。當你在Maven或Gradle構建工具中添加spring-boot-dependencies依賴時,它會自動引入這個BOM文件。你可以直接聲明其他Spring Boot相關的依賴項,并且這些依賴項會自動采用BOM中指定的版本。例如,你可以聲明spring-boot-starter-web依賴,并且該依賴會自動使用BOM中定義的Spring Boot版本。
使用spring-boot-dependencies可以帶來很多好處。首先,它可以統一管理所有的Spring Boot相關庫的版本,避免不同庫之間的版本沖突。其次,它可以簡化依賴項的管理,不需要在每個項目中手動指定每個庫的版本號。最后,它可以確保所使用的庫的版本兼容性和一致性,避免因版本不同導致的問題。
總之,spring-boot-dependencies是Spring Boot框架提供的一個版本控制機制,它可以簡化和統一項目中所使用的庫的版本管理,確保版本的兼容性和一致性。
- 新建一個空白項目,在
<dependency>
中添加SpringBoot
的依賴
其實就是沒有使用上面1/2說的這兩個做法咯。在這種情況下,需要我們自行去管理、確定依賴包的版本,容易出現兼容性問題。
通常,我們通過Spring Initializer
或者Ali在線云原生構建也好,生成出來的SpringBoot都是采用方案1、2。
不知道大家有沒有用心看我上面的介紹,我這邊最后再結合自己的理解,簡單的總結一下:
- 我們通常新建一個SpringBoot項目的時候,之所以在pom中繼承自
spring-boot-starter-parent
,主要是為了簡化配置。這些簡化配置包括:默認的JDK版本、默認的項目編碼格式UTF-8、自動化的資源配置、插件配置。最重要的是,spring-boot-starter-parent
繼承自spring-boot-dependencies
- 而在
spring-boot-dependencies
中,定義了一系列Spring開發中,常用的jar包依賴,根據我的發現,在里面主要是包含了國外知名廠商的jar包,比如org.apache
的東西 - 因為在
spring-boot-dependencies
里面預包含了很多jar包依賴,所以我們在實際使用中,很多jar包的引用不需要再顯式地指定version
。如下:
問題2:什么是SpringCloud,如何新建一個SpringCloud項目
我感覺在想通了問題1之后,對于這個問題我就沒多少疑惑了。盲猜SpringCloud就是提供了很多關于微服務開發常用的中間件jar包依賴。根據我的理解也確實是這樣
問題3:SpringCloudAlibaba和SpringCloud有什么關系
下面是我在【文心一言】看到的答案:
Spring Cloud Alibaba是Spring Cloud的子項目,符合Spring Cloud標準。它是一套完整的分布式解決方案,旨在推廣阿里的產品。如果使用了Spring Cloud Alibaba,最好使用alibaba整個體系產品。
因此,Spring Cloud Alibaba和Spring Cloud的關系是,前者是后者的一部分,符合后者的標準。
但其實我不是很贊同這個說法,我覺得多少有點不準確。通過查看spring-cloud-dependencies
和spring-cloud-alibaba-dependencies
會發現,他們只是繼承了同一個spring-cloud-dependencies-parent
項目而已,所以文心一言說Spring Cloud Alibaba是Spring Cloud的子項目,符合Spring Cloud標準
也沒錯。不過我個人認為:SpringCloud
是SpringCloud公司給出的一個通用分布式微服務技術合集。而Spring Cloud Alibaba
則是阿里給的一套,自己的解決方案,里面的微服務中間件都是阿里系的。說不定哪一天你就看到了Spring Cloud Tencent
、Spring Cloud ByteDance
、Spring Cloud HuaWei
我在后面將使用Spring Cloud Alibaba
,大家可以通過傳送門看看介紹:傳送門。根據官方介紹,我們想要使用Spring Cloud Alibaba
,只需要在pom中引入下面的依賴:
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${alibaba-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
附上一張,應該是Alibaba給出的分布式微服務生態圖:
四、SpringCloud升級整合
4.1 新建父子項目
使用IDEA新建一個父子項目,具體過程我就不貼了,如果你理解了【三、分布式微服務升級前的思考】的內容,最后發現也沒那么難。當然,有時候需要一點Maven相關知識,我這邊建議直接花半個小時看看【菜鳥教程Maven系列】,個人認為比較需要了解的是:Maven構建生命周期、Maven POM
新建出來之后就是一個父子項目咯,然后每個項目有自己的@SpringBootApplication
啟動類。
但顯然,這不是我們想要的結果,我們在【二、服務拆分】中提到的問題依然還沒有解決。如:
- 服務注冊與發現(微服務最重要的一個點)
- 分布式配置管理
- 服務限流降級
- 鏈路追蹤
- 分布式事務
- 等等
所以,接下來才是真正的重頭戲啊。后面我會逐步整合,下一篇則是整合Nacos配置中心到項目中。
學習總結
- 理解了SpringBoot跟SpringCloud項目的具體含義
- 對如何新建一個SpringBoot項目有個較為清晰的認知
感謝
感謝簡書大佬【作者:】的文章《理解spring-boot-starter-parent》