Spring Cloud實現(xiàn)微服務(wù)調(diào)用的負(fù)載均衡(詳解)
什么是負(fù)載均衡
通俗的講,負(fù)載均衡就是將負(fù)載(工作任務(wù),訪問請求)進(jìn)行分?jǐn)偟蕉鄠€操作單元(服務(wù)器,組件)上進(jìn)行執(zhí)行。
根據(jù)負(fù)載均衡發(fā)生位置的不同,一般分為服務(wù)端負(fù)載均衡和客戶端負(fù)載均衡。
- 服務(wù)端負(fù)載均衡指的是發(fā)生在服務(wù)提供者一方,比如常見的 nginx 負(fù)載均衡。
- 客戶端負(fù)載均衡指的是發(fā)生在服務(wù)請求的一方,也就是在發(fā)送請求之前已經(jīng)選好了由哪個實例處理請求。

我們在微服務(wù)調(diào)用關(guān)系中一般會選擇客戶端負(fù)載均衡,也就是在服務(wù)調(diào)用的一方來決定服務(wù)由哪個提供者執(zhí)行。
自定義實現(xiàn)負(fù)載均衡
啟動shop-product微服務(wù)
在啟動 shop-product 微服務(wù)的基礎(chǔ)上,通過idea再啟動一個 shop-product 微服務(wù),設(shè)置其端口為8082。

命令為-Dserver.port=8082
通過nacos查看微服務(wù)的啟動情況

自定義實現(xiàn)負(fù)載均衡
修改 shop-order 的代碼
public ShopOrder order(@PathVariable("pid") Long pid) {
log.info("客戶下單,這時候要調(diào)用商品微服務(wù)查詢商品信息。。。");
//從nacos中獲取服務(wù)地址
List<ServiceInstance> instances = discoveryClient.getInstances("shop-product");
//自定義規(guī)則實現(xiàn)隨機挑選服務(wù)
int index = new Random().nextInt(instances.size());
ServiceInstance serviceInstance = instances.get(index);
String url = serviceInstance.getHost()+":"+serviceInstance.getPort();
log.info(">>從nacos中獲取到的微服務(wù)地址為:"+ url);
//通過restTemplate調(diào)用商品微服務(wù)
ShopProduct shopProduct = restTemplate.getForObject("http://"+url+"/product/"+pid, ShopProduct.class);
log.info("當(dāng)前用戶信息為自己,假設(shè)我們設(shè)置為1");
ShopOrder shopOrder = new ShopOrder();
shopOrder.setUid(1L);
shopOrder.setUsername("公眾號:阿Q說代碼");
shopOrder.setPid(shopProduct.getId());
shopOrder.setPname(shopProduct.getPname());
orderService.save(shopOrder);
//商品扣減庫存的邏輯
ProductReduceDTO productReduceDTO = new ProductReduceDTO();
productReduceDTO.setProductId(pid);
productReduceDTO.setReductCount(1);
Integer count = restTemplate.postForObject("http://"+url+"/product/reduceStock", productReduceDTO, Integer.class);
return shopOrder;
}啟動兩個服務(wù)提供者和一個服務(wù)消費者,多訪問幾次消費者,測試效果:

基于Ribbon實現(xiàn)負(fù)載均衡
Ribbon 是Spring Cloud的一個組件,它可以讓我們使用一個注解就能輕松的搞定負(fù)載均衡。
添加注解
在 RestTemplate 的生成方法上添加@LoadBalanced注解
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}修改服務(wù)調(diào)用的方法
將上一步中的代碼注釋掉,改為直接使用微服務(wù)名字,從nacos中獲取服務(wù)地址
//從nacos中獲取服務(wù)地址
//自定義規(guī)則實現(xiàn)隨機挑選服務(wù)
//List<ServiceInstance> instances = discoveryClient.getInstances("shop-product");
//int index = new Random().nextInt(instances.size());
//ServiceInstance serviceInstance = instances.get(index);
//String url = serviceInstance.getHost()+":"+serviceInstance.getPort();
//直接使用微服務(wù)名字,從nacos中獲取服務(wù)地址
String url="shop-product";重啟服務(wù)進(jìn)行測試,微服務(wù)調(diào)用成功。
Ribbon支持的負(fù)載均衡策略
Ribbon內(nèi)置了多種負(fù)載均衡策略,內(nèi)部負(fù)載均衡的頂級接口為com.netflix.loadbalancer.IRule,具體的負(fù)載策略如下圖所示:

通過修改配置來調(diào)整 Ribbon 的負(fù)載均衡策略
# 負(fù)載均衡規(guī)則
shop-product:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule通過注入Bean來調(diào)整 Ribbon 的負(fù)載均衡策略
@Bean
public IRule randomRule(){
return new RandomRule();
}饑餓加載
為何要開啟饑餓加載,因為在我們第一次加載時候,響應(yīng)時間比較慢,原因是第一次加服務(wù)需要從服務(wù)注冊列表中拉取服務(wù)實例,以及初始化相關(guān)的組件到 Spring 中。
開啟饑餓加載的相關(guān)配置之后這些操作會在服務(wù)啟動就會完成。
ribbon:
eager-load:
clients:
- shop-product總結(jié)
到這兒,我們微服務(wù)調(diào)用的負(fù)載均衡實現(xiàn)就結(jié)束了。下一篇將為大家?guī)砘趂eign實現(xiàn)微服務(wù)調(diào)用的文章,敬請期待吧!
后續(xù)的文章,我們將繼續(xù)完善我們的微服務(wù)系統(tǒng),集成更多的Alibaba組件。想要了解更多JAVA后端知識,請點擊文末名片與我交流吧。留下您的一鍵三連,讓我們在這個寒冷的東西互相溫暖吧!

到此這篇關(guān)于Spring Cloud實現(xiàn)微服務(wù)調(diào)用的負(fù)載均衡的文章就介紹到這了,更多相關(guān)Spring Cloud微服務(wù)調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring?Cloud?Alibaba?Nacos服務(wù)治理平臺服務(wù)注冊、RestTemplate實現(xiàn)微服務(wù)之間訪問負(fù)載均衡訪問的問題
- SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式
- Spring Cloud多個微服務(wù)之間調(diào)用代碼實例
- spring cloud eureka微服務(wù)之間的調(diào)用詳解
- springcloud gateway如何實現(xiàn)路由和負(fù)載均衡
- Spring Cloud 負(fù)載均衡器 Ribbon原理及實現(xiàn)
- spring cloud 之 客戶端負(fù)載均衡Ribbon深入理解
相關(guān)文章
一文搞清楚Java中Comparable和Comparator的區(qū)別
Java中的Comparable和Comparator都是用于集合排序的接口,但它們有明顯的區(qū)別,文中通過一些實例代碼詳細(xì)介紹了Java中Comparable和Comparator的區(qū)別,感興趣的同學(xué)跟著小編一起學(xué)習(xí)吧2023-05-05
springboot服務(wù)正常啟動之后,訪問服務(wù)url無響應(yīng)問題及解決
這篇文章主要介紹了springboot服務(wù)正常啟動之后,訪問服務(wù)url無響應(yīng)問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
SpringBoot整合SQLite數(shù)據(jù)庫全過程
sqlite是一個很輕量級的數(shù)據(jù)庫,可以滿足日常sql的需求,下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合SQLite數(shù)據(jù)庫的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
Java怎樣創(chuàng)建集合才能避免造成內(nèi)存泄漏你了解嗎
內(nèi)存泄漏是指無用對象持續(xù)占有內(nèi)存或無用對象的內(nèi)存得不到及時釋放,從而造成內(nèi)存空間的浪費稱為內(nèi)存泄漏。長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄漏,盡管短生命周期對象已經(jīng)不再需要,但是因為長生命周期持有它的引用而導(dǎo)致不能被回收2021-09-09
Java利用apache ftp工具實現(xiàn)文件上傳下載和刪除功能
這篇文章主要為大家詳細(xì)介紹了Java利用apache ftp工具實現(xiàn)文件上傳下載、刪除功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06
Java實現(xiàn)將數(shù)組的元素用逗號連接的多種方法
在 Java 開發(fā)中,我們經(jīng)常需要將數(shù)組中的元素用逗號連接成一個字符串,這種需求在日志記錄、數(shù)據(jù)導(dǎo)出、API 響應(yīng)等場景中非常常見,本文將詳細(xì)介紹如何在 Java 中實現(xiàn)這一功能,并提供多種簡潔的方法和優(yōu)化建議,需要的朋友可以參考下2025-01-01

