动态

详情 返回 返回

【Spring開發】SpringCloud服務端基礎框架第6篇:4.Ribbon負載均衡,5.Nacos註冊中心【附代碼 - 动态 详情

🏆🏆🏆教程全知識點簡介:Docker實用篇 0.學習目標 1.初識Docker 1.2.Docker和虛擬機的區別 2.Docker的基本操作 2.1.鏡像操作 2.1.3.案例1-拉取、查看鏡像 2.1.5.練習 3.Dockerfile自定義鏡像 3.3.構建Java項目 3.4.小結 4.Docker-Compose 4.3.部署微服務集羣 4.3.1.compose文件 4.3.3.打包 設置docker鏡像源 關閉 禁止開機啓動防火牆 安裝 修改權限 補全命令 RabbitMQ 1.初識MQ 1.1.同步和異步通訊 1.2.技術對比: 2.快速入門 2.2.RabbitMQ消息模型 2.3.導入Demo工程 2.4.入門案例 2.4.1.publisher實現 3.1.3.測試 3.2.WorkQueue 3.2.1.消息發送 3.2.4.能者多勞 3.3.發佈/訂閲 3.4.Fanout 3.4.1.聲明隊列和交換機 3.5.Direct 3.6.Topic 3.6.1.説明 SpringCloud01 1.認識微服務 1.1.單體架構 2.服務拆分和遠程調用 2.1.服務拆分原則 2.3.實現遠程調用案例 2.3.1.案例需求: 2.3.2.註冊RestTemplate 3)啓動多個user-service實 4.Ribbon負載均衡 4.1.負載均衡原理 4.2.源碼跟蹤 1)LoadBalancerIntercepor 3)負載均衡策略IRule 5.Nacos註冊中心 5.1.認識和安裝Nacos 5.2.服務註冊到nacos 1)引入依賴 2)配置nacos地址 3)重啓 5.3.服務分級存儲模型 5.3.2.同集羣優先的負載均衡 5.4.權重配置 Nacos安裝指南 1.Windows安裝 1.1.下載安裝包 1.2.解壓 1.3.端口配置 1.4.啓動 1.5.訪問 2.Linux安裝 2.1.安裝JDK 3.Gateway服務網關 3.1.為什麼需要網關 3.3.斷言工廠

<!-- start:bj1 -->

📚📚倉庫code.zip 👉直接-->:   https://gitlab.com/yiqing112/backend/-/blob/main/Spring/Sprin...    🍅🍅

<!-- end:bj1 -->

✨ 本教程項目亮點

🧠 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
💻 全技術鏈覆蓋:完整前後端技術棧,涵蓋開發必備技能
🚀 從零到實戰:適合 0 基礎入門到提升,循序漸進掌握核心能力
📚 豐富文檔與代碼示例:涵蓋多種場景,可運行、可複用
🛠 工作與學習雙參考:不僅適合系統化學習,更可作為日常開發中的查閲手冊
🧩 模塊化知識結構:按知識點分章節,便於快速定位和複習
📈 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考

🎯🎯🎯全教程總章節


🚀🚀🚀本篇主要內容

4.Ribbon負載均衡

上一節中, 添加了@LoadBalanced註解,即可實現負載均衡功能,這是什麼原理呢?

4.1.負載均衡原理

SpringCloud底層其實是利用了一個名為Ribbon的組件,來實現負載均衡功能的。

那麼 發出的請求明明是http://userservice/user/1,怎麼變成了http://localhost:8081的呢?

4.2.源碼跟蹤

為什麼 只輸入了service名稱就可以訪問了呢?之前還要獲取ip和端口。

顯然有人幫 根據service名稱,獲取到了服務實例的ip和端口。它就是LoadBalancerInterceptor,這個類會在對RestTemplate的請求進行攔截,然後從Eureka根據服務id獲取服務列表,隨後利用負載均衡算法得到真實的服務地址信息,替換服務id。

進行源碼跟蹤:

1)LoadBalancerIntercepor

可以看到這裏的intercept方法,攔截了用户的HttpRequest請求,然後做了幾件事:

  • request.getURI():獲取請求uri,本例中就是 http://user-service/user/8
  • originalUri.getHost():獲取uri路徑的主機名,其實就是服務id,user-service
  • this.loadBalancer.execute():處理服務id,和用户請求。

這裏的this.loadBalancerLoadBalancerClient類型, 繼續跟入。

Dropwizard 文檔

2)LoadBalancerClient

繼續跟入execute方法:

代碼是這樣的:

  • getLoadBalancer(serviceId):根據服務id獲取ILoadBalancer,而ILoadBalancer會拿着服務id去eureka中獲取服務列表並保存起來。
  • getServer(loadBalancer):利用內置的負載均衡算法,從服務列表中選擇一個。本例中,可以看到獲取了8082端口的服務

放行後,再次訪問並跟蹤,發現獲取的是8081:

果然實現了負載均衡。

3)負載均衡策略IRule

在剛才的代碼中,可以看到獲取服務使通過一個getServer方法來做負載均衡:

繼續跟入:

JDK 17 API 文檔

繼續跟蹤源碼chooseServer方法,發現這麼一段代碼:

看看這個rule是誰:

這裏的rule默認值是一個RoundRobinRule,看類的介紹:

這不就是輪詢的意思嘛。

到這裏,整個負載均衡的流程 就清楚了。

4)總結

SpringCloudRibbon的底層採用了一個攔截器,攔截了RestTemplate發出的請求,對地址做了修改。用一幅圖來總結一下:

基本流程如下:

  • 攔截 的RestTemplate請求http://userservice/user/1
  • RibbonLoadBalancerClient會從請求url中獲取服務名稱,也就是user-service
  • DynamicServerListLoadBalancer根據user-service到eureka拉取服務列表
  • eureka返回列表,localhost:8081、localhost:8082
  • IRule利用內置負載均衡規則,從列表中選擇一個,例如localhost:8081
  • RibbonLoadBalancerClient修改請求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,發起真實請求

4.3.負載均衡策略

4.3.1.負載均衡策略

負載均衡的規則都定義在IRule接口中,而IRule有很多不同的實現類:

不同規則的含義如下:

內置負載均衡規則類 規則描述
RoundRobinRule 簡單輪詢服務列表來選擇服務器。它是Ribbon默認的負載均衡規則。
AvailabilityFilteringRule 對以下兩種服務器進行忽略: (1)在默認情況下,這台服務器如果3次連接失敗,這台服務器就會被設置為“短路”狀態。短路狀態將持續30秒,如果再次連接失敗,短路的持續時間就會幾何級地增加。 (2)併發數過高的服務器。如果一個服務器的併發連接數過高,配置了AvailabilityFilteringRule規則的客户端也會將其忽略。併發連接數的上限,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit屬性進行配置。
WeightedResponseTimeRule 為每一個服務器賦予一個權重值。服務器響應時間越長,這個服務器的權重就越小。這個規則會隨機選擇服務器,這個權重值會影響服務器的選擇。
ZoneAvoidanceRule 以區域可用的服務器為基礎進行服務器的選擇。使用Zone對服務器進行分類,這個Zone可以理解為一個機房、一個機架等。而後再對

5.Nacos註冊中心

國內公司一般都推崇阿里巴巴的技術,比如註冊中心,SpringCloudAlibaba也推出了一個名為Nacos的註冊中心。

5.1.認識和安裝Nacos

Nacos是阿里巴巴的產品,現在是SpringCloud中的一個組件。相比Eureka功能更加豐富,在國內受歡迎程度較高。

安裝方式可以參考課前資料《Nacos安裝指南.md》

5.2.服務註冊到nacos

Nacos是SpringCloudAlibaba的組件,而SpringCloudAlibaba也遵循SpringCloud中定義的服務註冊、服務發現規範。因此使用Nacos和使用Eureka對於微服務來説,並沒有太大區別。

主要差異在於:

  • 依賴不同
  • 服務地址不同

1)引入依賴

在cloud-demo父工程的pom文件中的<dependencyManagement>中引入SpringCloudAlibaba的依賴:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

然後在user-service和order-service中的pom文件中引入nacos-discovery依賴:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
注意:不要忘了註釋掉eureka的依賴。

2)配置nacos地址

在user-service和order-service的application.yml中添加nacos地址:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
注意:不要忘了註釋掉eureka的地址

3)重啓

WireMock 文檔

重啓微服務後,登錄nacos管理頁面,可以看到微服務信息:

5.3.服務分級存儲模型

一個服務可以有多個實例,例如 的user-service,可以有:

  • 127.0.0.1:8081
  • 127.0.0.1:8082
  • 127.0.0.1:8083

假如這些實例分佈於全國各地的不同機房,例如:

  • 127.0.0.1:8081,在上海機房
  • 127.0.0.1:8082,在上海機房
  • 127.0.0.1:8083,在杭州機房

Nacos就將同一機房內的實例 劃分為一個集羣

也就是説,user-service是服務,一個服務可以包含多個集羣,如杭州、上海,每個集羣下可以有多個實例,形成分級模型,如圖:

微服務互相訪問時,應該儘可能訪問同集羣實例,因為本地訪問速度更快。當本集羣內不可用時,才訪問其它集羣。例如:

杭州機房內的order-service應該優先訪問同機房的user-service。

5.3.1.給user-service配置集羣

修改user-service的application.yml文件,添加集羣配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集羣名稱

重啓兩個user-service實例後, 可以在nacos控制枱看到下面結果:

再次複製一個user-service啓動配置,添加屬性:

-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH

配置如圖所示:

啓動UserApplication3後再次查看nacos控制枱:

5.3.2.同集羣優先的負載均衡

默認的ZoneAvoidanceRule並不能實現根據同集羣優先來實現負載均衡。

因此Nacos中提供了一個NacosRule的實現,可以優先從同集羣中挑選實例。

1)給order-service配置集羣信息

修改order-service的application.yml文件,添加集羣配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集羣名稱

2)修改負載均衡規則

修改order-service的application.yml文件,修改負載均衡規則:

userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 負載均衡規則 

5.4.權重配置

實際部署中會出現這樣的場景:

服務器設備性能有差異,部分實例所在機器性能較好,另一些較差, 希望性能好的機器承擔


🚀✨ (未完待續)項目系列下一章

📚下一篇 將進入更精彩的環節!
🔔 記得收藏 & 關注,第一時間獲取更新!
🍅 一起見證整個系列逐步成型的全過程。

Add a new 评论

Some HTML is okay.