一.Ribbon負載均衡
在上一節中,我們通過在RestTemplte實例中加上了注解 @LoadBalanced,表示將來由RestTemplate發起的請求會被Ribbon攔截和處理,實現了訪問服務時的負載均衡,那么他是如何實現的呢?
1.1 Ribbon負載均衡的原理
Ribbon實現負載均衡的流程如上圖所示,order-service需要請求user-service的服務,根據user-service在eureka注冊中心的注冊的服務名稱是userservice,order-service直接使用usersivce作為“IP地址+端口號”進行訪問,發起了請求http:userservice/user/1,然后Ribbon會收到該請求,于是訪問eureka注冊中心拉取userservice所有的服務列表,然后負載均衡訪問中的一個。
具體的Ribbon的負載均衡實現原理如上圖所示:
- 1.order-service發送的請求會被LoadBalancerInterceptor負載均衡攔截器攔截
- 2.由RibbonLoadBanlancerClient獲取url中的服務id(就是你注冊的服務名稱)userservice
- 3.將該服務id交給DynamicServerListLoadBalancer,從eureka注冊中心中拉取服務列表,并根據IRule選擇一個負載均衡的策略,比如隨機調度,輪詢調度等選擇某個服務。
- 4.將該服務返回給RibbonLoadBanlacnedClient
- 5.RibbonLoadBanlacnedClient修改url并發起請求。
1.2 Ribbon負載均衡的策略
有多種負載均衡的策略,默認是輪詢,如果想要自己修改負載均衡的策略,需要在對應的服務中(該服務訪問其他服務)進行配置.
方式一
代碼方式,在比如order-service的application中提供一個定義一個新的IRule,該方式是全局配置,只要配置之后,無論是在order-service中調用哪個微服務,都會執行該負載均衡的策略;
/*** 代碼方式配置負載均衡策略* @return*/@Beanpublic IRule randomRule(){return new RandomRule();}
方式二
配置yml方式,局部配置,配置某一個微服務的訪問時的負載均衡的策略。
# 配置某個服務的負載均衡策略
userservice:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 負載均衡的策略
1.3 Ribbon饑餓加載
首先,明確什么是懶加載與饑餓加載?
??懶加載(Lazy Loading)是一種延遲加載數據或資源的策略,它通常在需要時才加載數據,而不是在初始化時就立即加載。這個概念在軟件開發中經常被用來提高性能和減少資源消耗。
??“饑餓加載”(Eager Loading)是一種加載數據或資源的策略,它與懶加載相對。在饑餓加載中,數據或資源在初始化或啟動時就被加載,而不管是否立即需要使用。
??Ribbon默認是采用懶加載,即第一次訪問時才會創建LoadBanlacnedClient,因此第一次請求的時間會很長,但之后就好了(因為加載好的內容會被緩存到內存中)。
??修改Ribbon的加載方式為饑餓加載,于是便會在項目啟東時就創建LoadBanlacnedClient,降低第一次訪問的耗時,通過配置的方式開啟饑餓加載。
# 配置饑餓加載
ribbon:eager-load:enabled: true
二.Nacos安裝與入門
Nacos(全稱為"Dynamic Naming and Configuration Service")是阿里巴巴開源的一款服務發現、配置管理和服務管理平臺。它可以幫助開發者輕松構建云原生應用,實現動態服務發現、服務注冊與配置管理,并提供服務治理、流量管理等功能。
2.1 認識Nacos
Nacos也是服務注冊中心,但是相對Eureka有著更加豐富的功能,且在國內更受歡迎。
2.2 安裝Nacos
當前使用的Nacos的版本是1.4.1,直接解壓安裝包即可。可以在nacos/conf目錄下的application.properties文件中修改端口號信息,默認是8848(8848鈦金手機,成功男人的標志)。
2.3 啟動Nacos
進入Nacos安裝目錄下的bin目錄,輸入命令:
startup.cmd -m standalone
啟動成功截圖,然后按住ctrl+點擊啟動地址即可啟動
登陸的默認賬號和密碼都是nacos,登陸成功頁面
2.4 Nacos快速入門
由于Nacos是后續加入的,所以父工程spring-cloud的依賴并不包含之,需要在父工程中額外加入Nacos管理依賴。
1.修改依賴
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>
將user-service,order-service中的原來eureka客戶端依賴注釋掉,修改為nacos客戶端依賴。
<!-- nacos客戶端依賴包 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.修改配置文件
注釋掉user-service,order-service的eureka服務注冊信息的配置
在spring相關配置中添加:
cloud:nacos:server-addr: localhost:8848 # nacos服務地址
然后啟動即可,nacos與eureka的其他代碼都相同,只需要修改配置文件和導入依賴即可。修改之后直接啟動各個服務,隨后各個服務會被注冊到nacos注冊中心之中,如下圖所示:
2.5 Nacos服務分級存儲模型
Nacos還引入了服務集群的概念,在一個服務可以包含多個實例的同時(這點與eureka相同),每個實例還會有一個隸屬的集群,比如北京集群,上海集群,廣州集群,深圳集群,在一個服務需要調用另一個服務時應該盡可能的調用本地集群的服務,這樣速度更快,延遲更低。
為服務實例配置集群屬性
spring:cloud:nacos:discovery:cluster-name: HZ # 集群名稱
配置好之后,啟動user-service,user-service(1);
然后再修改集群名稱為另一個:
spring:cloud:nacos:discovery:cluster-name: SH # 集群名稱
再啟動user-service(2).
此時user-service,user-service(1);會被部署到hz集群,user-service(2)會被部署到sh集群.
2.6 NacosRuler負載均衡
決定負載均衡的策略完全是由IRule決定的,當前order-service使用的是隨機負載均衡策略
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 負載均衡的策略
那么并不會按照集群本地訪問優先的規則進行訪問。所以修改負載均衡策略為NacosRule,優先選擇本地集群,本地集群內使用隨機方式訪問。
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 負載均衡的策略
配置之后,會優先訪問同集群內服務user-service(hz集群)
user-service(1)(hz集群)
user-service(2)(sh集群)
當停掉HZ服務之后,只剩下SH服務:
仍能訪問成功,但是order-service控制臺會給出一個警告信息,提醒這是一個跨越集群的訪問:
2.7 NacosRuler負載均衡的權重設置
當出現不同機器需要承擔不同比例的請求時,就不能單純的按照優先本地集群,集群內隨機的方式負載均衡了。需要配置權重。直接在Nacos控制臺配置權重即可,配置的權重通常是0-1之間,當某個服務的權重為0時,表示該服務不會被任何用戶訪問(可以用于不停服更新,絲滑過渡等場景)。
2.8 NacosRuler負載均衡的權重設置
Nacos中服務存儲和數據存儲的最外層都是一個名為namespace的東西,用來做外層隔離。
namespace可以用于隔離開發環境,生產環境,測試環境等。
通過nacos控制臺新建一個命名空間dev
可以看到,新建的命名空間dev中沒有任何服務。
如果要修改服務所在命名空間,需要在代碼中修改對應的服務yml配置文件。
spring:cloud:nacos:discovery:namespace: d3811bbe-1b14-449f-b984-85bdbcdf16dd # 命名空間ID
添加上述代碼到order-service中,重啟order-service服務,刷新nacos控制臺,發現public命名空間中只剩下一個user-service;
命名空間dev中卻有了order-service
此時由于二者位于不同的命名空間,二者便無法再相互訪問…
2.9 Nacos與Eureka注冊中心的比較
二者訪問服務的邏輯基本一致。
區別一:服務提供者的健康檢測
??Nacos分為臨時實例和非臨時實例,二者的健康檢測是不同的,臨時實例的健康檢測同Eureka,每隔30s向nacos注冊中心報告一次狀態(心跳檢測),如果nacos注冊中心在一定時間內未收到臨時實例的報告,會直接認為該服務已經掛掉了,將該服務直接從列表中剔除。而非臨時實例則是nacos主動詢問目標服務,即使非臨時服務掛掉了,nacos注冊中心也不會把非臨時實例從列表中剔除,而是會等著該服務,等著該服務回復健康。
區別二:服務消費者的獲取服務方式不同
??eureka的服務消費者只通過定時拉取服務的方式拉取服務列表pull,由于是定時拉取,因此當服務列表更新時,可能更新之后的服務獲取不及時。
??nacos的服務消費者不僅通過定時拉取服務的方式拉取服務列表pull,同時加入主動推送變更消息的機制push,這樣當服務變更時可以及時的提醒服務消費者。
設置臨時實例/非臨時實例
默認為臨時實例,在修改配置之后變為非臨時實例。
spring:cloud:nacos:discovery:ephemeral: false # 設置為非臨時實例