網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
文章目錄
- 1. Ribbon負(fù)載均衡
- 1.1 負(fù)載均衡原理
- 1.2 源碼跟蹤
- 1)LoadBalancerInterceptor
- 1)LoadBalancerClient
- 3)負(fù)載均衡策略IRule
- 4)總結(jié)
- 1.3 負(fù)載均衡策略
- 1.3.1.負(fù)載均衡策略
- 1.3.2.自定義負(fù)載均衡策略
- 1.4 饑餓加載
1. Ribbon負(fù)載均衡
學(xué)習(xí)Eruaka的時(shí)候,我們添加了@LoadBalanced注解,就可實(shí)現(xiàn)負(fù)載均衡功能,這是什么原理呢?
1.1 負(fù)載均衡原理
SpringCloud底層其實(shí)是利用了一個(gè)名為Ribbon的組件,來(lái)實(shí)現(xiàn)負(fù)載均衡功能的。
那么我們發(fā)出的請(qǐng)求明明是http://userservice/user/1
,怎么變成了http://localhost:8081
的呢?
1.2 源碼跟蹤
為什么我們只輸入了service名稱就可以訪問(wèn)了呢?之前還要獲取ip和端口。
顯然有人幫我們根據(jù)service名稱,獲取到了服務(wù)實(shí)例的ip和端口。它就是LoadBalancerInterceptor
,這個(gè)類會(huì)在對(duì)RestTemplate的請(qǐng)求進(jìn)行攔截,然后從Eureka根據(jù)服務(wù)id獲取服務(wù)列表,隨后利用負(fù)載均衡算法得到真實(shí)的服務(wù)地址信息,替換服務(wù)id。
我們對(duì)LoadBalancerInterceptor進(jìn)行源碼跟蹤:
1)LoadBalancerInterceptor
可以看到這里的intercept方法,攔截了用戶的HttpRequest請(qǐng)求,然后做了幾件事:
-
request.getURI()
:獲取請(qǐng)求uri,本例中就是 http://user-service/user/8 -
originalUri.getHost()
:獲取uri路徑的主機(jī)名,其實(shí)就是服務(wù)id,user-service
-
this.loadBalancer.execute()
:處理服務(wù)id,和用戶請(qǐng)求。
這里的this.loadBalancer
是LoadBalancerClient
類型,我們繼續(xù)跟入execute。
1)LoadBalancerClient
找到LoadBalancerClient接口,繼續(xù)跟入execute方法,找到實(shí)現(xiàn)接口的子類:
代碼是這樣的:
- getLoadBalancer(serviceId):根據(jù)服務(wù)id獲取ILoadBalancer,而ILoadBalancer會(huì)拿著服務(wù)id去eureka中獲取服務(wù)列表并保存起來(lái)。
- getServer(loadBalancer):利用內(nèi)置的負(fù)載均衡算法,從服務(wù)列表中選擇一個(gè)。本例中,可以看到獲取了8082端口的服務(wù)
放行后,再次訪問(wèn)并跟蹤,發(fā)現(xiàn)獲取的是8081:
果然實(shí)現(xiàn)了負(fù)載均衡。
3)負(fù)載均衡策略IRule
在剛才的代碼中,可以看到獲取服務(wù)使通過(guò)一個(gè)getServer
方法來(lái)做負(fù)載均衡:
我們繼續(xù)跟入:
繼續(xù)跟蹤源碼chooseServer方法,發(fā)現(xiàn)這么一段代碼:
我們看看這個(gè)rule是誰(shuí):
這里的rule默認(rèn)值是一個(gè)RoundRobinRule
,看類的介紹:
這不就是輪詢的意思嘛。
到這里,整個(gè)負(fù)載均衡的流程我們就清楚了。
4)總結(jié)
SpringCloudRibbon的底層采用了一個(gè)攔截器,攔截了RestTemplate發(fā)出的請(qǐng)求,對(duì)地址做了修改。用一幅圖來(lái)總結(jié)一下:
基本流程如下:
- 攔截我們的RestTemplate請(qǐng)求http://userservice/user/1
- RibbonLoadBalancerClient會(huì)從請(qǐng)求url中獲取服務(wù)名稱,也就是user-service
- DynamicServerListLoadBalancer根據(jù)user-service到eureka拉取服務(wù)列表
- eureka返回列表,localhost:8081、localhost:8082
- IRule利用內(nèi)置負(fù)載均衡規(guī)則,從列表中選擇一個(gè),例如localhost:8081
- RibbonLoadBalancerClient修改請(qǐng)求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,發(fā)起真實(shí)請(qǐng)求
1.3 負(fù)載均衡策略
1.3.1.負(fù)載均衡策略
負(fù)載均衡的規(guī)則都定義在IRule接口中,而IRule有很多不同的實(shí)現(xiàn)類:
不同規(guī)則的含義如下:
內(nèi)置負(fù)載均衡規(guī)則類 | 規(guī)則描述 |
---|---|
RoundRobinRule | 簡(jiǎn)單輪詢服務(wù)列表來(lái)選擇服務(wù)器。它是Ribbon默認(rèn)的負(fù)載均衡規(guī)則。 |
AvailabilityFilteringRule | 對(duì)以下兩種服務(wù)器進(jìn)行忽略: (1)在默認(rèn)情況下,這臺(tái)服務(wù)器如果3次連接失敗,這臺(tái)服務(wù)器就會(huì)被設(shè)置為“短路”狀態(tài)。短路狀態(tài)將持續(xù)30秒,如果再次連接失敗,短路的持續(xù)時(shí)間就會(huì)幾何級(jí)地增加。 (2)并發(fā)數(shù)過(guò)高的服務(wù)器。如果一個(gè)服務(wù)器的并發(fā)連接數(shù)過(guò)高,配置了AvailabilityFilteringRule規(guī)則的客戶端也會(huì)將其忽略。并發(fā)連接數(shù)的上限,可以由客戶端的..ActiveConnectionsLimit屬性進(jìn)行配置。 |
WeightedResponseTimeRule | 為每一個(gè)服務(wù)器賦予一個(gè)權(quán)重值。服務(wù)器響應(yīng)時(shí)間越長(zhǎng),這個(gè)服務(wù)器的權(quán)重就越小。這個(gè)規(guī)則會(huì)隨機(jī)選擇服務(wù)器,這個(gè)權(quán)重值會(huì)影響服務(wù)器的選擇。 |
ZoneAvoidanceRule | 以區(qū)域可用的服務(wù)器為基礎(chǔ)進(jìn)行服務(wù)器的選擇。使用Zone對(duì)服務(wù)器進(jìn)行分類,這個(gè)Zone可以理解為一個(gè)機(jī)房、一個(gè)機(jī)架等。而后再對(duì)Zone內(nèi)的多個(gè)服務(wù)做輪詢。 |
BestAvailableRule | 忽略那些短路的服務(wù)器,并選擇并發(fā)數(shù)較低的服務(wù)器。 |
RandomRule | 隨機(jī)選擇一個(gè)可用的服務(wù)器。 |
RetryRule | 重試機(jī)制的選擇邏輯 |
默認(rèn)的實(shí)現(xiàn)就是ZoneAvoidanceRule,是一種輪詢方案
1.3.2.自定義負(fù)載均衡策略
通過(guò)定義IRule實(shí)現(xiàn)可以修改負(fù)載均衡規(guī)則,有兩種方式:
-
代碼方式:在order-service中的OrderApplication類中,定義一個(gè)新的IRule:
@Bean public IRule randomRule(){ return new RandomRule(); }
-
配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改規(guī)則:
userservice: # 給某個(gè)微服務(wù)配置負(fù)載均衡規(guī)則,這里是userservice服務(wù) ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 負(fù)載均衡規(guī)則
注意,一般用默認(rèn)的負(fù)載均衡規(guī)則,不做修改。
1.4 饑餓加載
Ribbon默認(rèn)是采用懶加載,即第一次訪問(wèn)時(shí)才會(huì)去創(chuàng)建LoadBalanceClient,請(qǐng)求時(shí)間會(huì)很長(zhǎng)。
第一次請(qǐng)求:1s
再請(qǐng)求就非常快了:
而饑餓加載則會(huì)在項(xiàng)目啟動(dòng)時(shí)創(chuàng)建,降低第一次訪問(wèn)的耗時(shí),通過(guò)下面配置開(kāi)啟饑餓加載:
ribbon:
eager-load:
enabled: true
clients: userservice
原文鏈接:https://blog.csdn.net/weixin_45525272/article/details/125849415
相關(guān)推薦
- 2022-03-29 詳解python字符串相關(guān)str_python
- 2022-11-17 Android形狀圖形與狀態(tài)列表圖形及九宮格圖片超詳細(xì)講解_Android
- 2022-10-10 基于?Spring?Aop?環(huán)繞通知實(shí)現(xiàn)?Redis?緩存雙刪功能(示例代碼)_Redis
- 2022-05-15 require和import的區(qū)別詳解
- 2022-11-21 Redis不同數(shù)據(jù)類型的命令語(yǔ)句詳解_Redis
- 2021-12-06 Ubuntu編譯內(nèi)核模塊,內(nèi)容體現(xiàn)系統(tǒng)日志中_Linux
- 2023-11-26 (有效解決)Android Studio 運(yùn)行項(xiàng)目時(shí)報(bào) Package install error:
- 2023-10-15 [element-ui] el-input 不能正常輸入,輸入了也不能刪除的問(wèn)題
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支