負載均衡 LoadBalance

問題引入

我們一個服務可能會進行多機部署,也就說多臺服務器組成的集群共同對外提供一致的服務,那么我們的微服務的代碼就需要拷貝多份,部署到不同的機器上。

我們使用 IDEA 來開啟多個相同的服務
這里以 product-service 為例:

找到 services 按鍵,點開來:

在這里插入圖片描述

找到我們需要多機部署的服務,右鍵然后點擊 Copy Configuration ,復制這個服務的所有配置。

在這里插入圖片描述

之后就是給我們新的服務命名,然后點擊 Modify options 修改配置信息。

在這里插入圖片描述

點擊 Add VM options
在這里插入圖片描述

在 VM options 添加端口信息:

-Dserver.port=端口號

注意由于我們是在本機部署多個服務,所以端口號需要修改,避免端口的沖突

在這里插入圖片描述

最后點擊 Apply ,然后 OK,就可以創建成功了。


然后我們啟動所有的服務,在 Eureka 界面可以看到我們的 product-service 有多個注冊信息

在這里插入圖片描述

這里使用 order-service 來注冊發現 product-service:

@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;public OrderInfo getOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectById(orderId);
//        String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();//從 eureka 中獲取服務信息List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();String url = uri + "/product/" + orderInfo.getProductId();log.info("訪問的資源路徑:" + url);ProductDetailInfo productDetailInfo = restTemplate.getForObject(url, ProductDetailInfo.class);orderInfo.setProductDetailInfo(productDetailInfo);return orderInfo;}
}

但是我們發現多個請求,即使 product-service 有三個一樣的服務,但是使用的都是 9092,如果我們的請求類一旦上升,就可能會導致 9092這個服務器崩潰,我們應該要做到均衡地將這些請求發送給 product-service 的三個不同的服務器中,這就是我們本章要提到的負載均衡

在這里插入圖片描述

負載均衡

概念

負載均衡(Load Balance,簡稱LB),是高并發, 高可用系統必不可少的關鍵組件.
當服務流量增大時,通常會采用增加機器的方式進行擴容,負載均衡就是用來在多個機器或者其他資源中,按照一定的規則合理分配負載.

分類

負載均衡分為服務端負載均衡和客戶端負載均衡

服務端負載均衡,主要使用的是負載均衡器 Nginx,請求先到達負載均衡器,然后通過負載均衡算法在多個服務器之間選擇一個進行訪問

在這里插入圖片描述


客戶端負載均衡:
將負載均衡的功能以庫的方式集成到客戶端中,而不是由一臺負載均衡設備集中提供

在這里插入圖片描述

模擬實現

這里我們使用原子類,避免發生線程不安全,通過原子類的數值和我們獲取到的服務注冊列表的長度進行取余獲取下標,以輪詢的方式來訪問 product-service 服務端。

@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;private static final AtomicInteger count = new AtomicInteger(1);private List<ServiceInstance> instances;@PostConstructpublic void init() {instances = instances = discoveryClient.getInstances("product-service");}public OrderInfo getOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectById(orderId);
//        String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();int index = count.getAndIncrement() % instances.size();String uri = instances.get(index).getUri().toString();String url = uri + "/product/" + orderInfo.getProductId();log.info("訪問的資源路徑:" + url);ProductDetailInfo productDetailInfo = restTemplate.getForObject(url, ProductDetailInfo.class);orderInfo.setProductDetailInfo(productDetailInfo);return orderInfo;}
}

但是這個實現方式也有缺陷,就是如果后續有新的服務注冊或者舊的服務崩潰的話,我們的 order-service 就不會獲得到最新的注冊列表,導致后續出現 bug

即使你采用下面的方式,每次 order-service 處理請求都要進行重新獲取服務列表,也還是會出現 bug ,那就是如果舊的服務崩潰,可能無法即使獲取,導致出現ConnectException

java.net.ConnectException: Connection refused: connect
@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;private static final AtomicInteger count = new AtomicInteger(1);//    private List<ServiceInstance> instances;
//
//    @PostConstruct
//    public void init() {
//        instances = instances = discoveryClient.getInstances("product-service");
//    }public OrderInfo getOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectById(orderId);
//        String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();List<ServiceInstance> instances = discoveryClient.getInstances("product-service");int index = count.getAndIncrement() % instances.size();String uri = instances.get(index).getUri().toString();String url = uri + "/product/" + orderInfo.getProductId();log.info("訪問的資源路徑:" + url);ProductDetailInfo productDetailInfo = restTemplate.getForObject(url, ProductDetailInfo.class);orderInfo.setProductDetailInfo(productDetailInfo);return orderInfo;}
}

LoadBalance

SpringCloud從2020.0.1版本開始,移除了Ribbon組件,使用Spring Cloud LoadBalancer組件來代替Ribbon實現客戶端負載均衡

使用

添加注解 @LoadBalanced

在 RestTemplate 上添加 @LoadBalanced
將 RestTemplate 交給 LoadBalance 管理

@Configuration
public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

修改遠程調用的代碼

修改 String url = “http://product-service/product/” + orderInfo.getProductId();
將 ip 和端口號修改為 服務名稱【product-service】,這樣 LoadBalance會自動為我們提供服務端

@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;public OrderInfo getOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectById(orderId);String url = "http://product-service/product/" + orderInfo.getProductId();log.info("訪問的資源路徑:" + url);ProductDetailInfo productDetailInfo = restTemplate.getForObject(url, ProductDetailInfo.class);orderInfo.setProductDetailInfo(productDetailInfo);return orderInfo;}
}

負載均衡策略

負載均衡策略是一種思想,無論是哪種負載均衡器,它們的負載均衡策略都是相似的 SpringCloud
LoadBalancer僅支持兩種負載均衡策略:輪詢策略和隨機策略

1.輪詢(RoundRobin):輪詢策略是指服務器輪流處理用戶的請求.這是一種實現最簡單,也最常用的策略.生活中也有類似的場景,比如學校輪流值日,或者輪流打掃衛生.

2.隨機選擇(Random):隨機選擇策略是指隨機選擇一個后端服務器來處理新的請求

自定義負載均衡策略

SpringCloud LoadBalancer默認負載均衡策略是輪詢策略,實現是RoundRobinLoadBalancer,如果服務的消費者如果想采用隨機的負載均衡策略,也非常簡單。

官方鏈接:SpringCloud LoadBalancer

public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

CustomLoadBalancerConfiguration 這個類不用加類注解【@Configuration】
因為這個類是在組件的掃描范圍內

@LoadBalancerClient(name = "product-service", configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

我們在 RestTemplate 上添加 @LoadBalancerClient 注解,將服務名稱和負載策略填寫進去

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916999.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

13. 若依框架中的 Sensitive 敏感字段過濾

若依框架中有Sensitive注解&#xff0c;但代碼中并未使用&#xff0c;但該注解的實現還是比較值的學習的。該注解是一個運行時注解該注解只能應用在字段上JacksonAnnotationsInside 表示當使用Jackson序列化時&#xff0c;Jackson會自動識別該注解下的其他Jackson相關注解&…

git本地倉庫,工作區和暫存區的知識

一 git工作原理 Git 的工作原理基于分布式版本控制&#xff0c;通過管理文件的不同版本狀態&#xff0c;實現代碼的追蹤、協作和回溯。除了常見的工作區&#xff08;Working Directory&#xff09; 和暫存區&#xff08;Staging Area/Index&#xff09;&#xff0c;核心還包括本…

MPU6050模塊

一&#xff1a;MPU6050簡介輸出一個隨姿態變化而變化的電壓&#xff0c;想要量化電壓&#xff0c;就得使用ADC轉化歐拉角偏航角&#xff08;Yaw&#xff09;&#xff1a;也叫航向角&#xff0c;通常是繞 z 軸旋轉的角度&#xff0c;以 x 軸正向為起始邊&#xff0c;旋轉后 x 軸…

jvm的棧和堆

在 JVM 中&#xff0c;棧&#xff08;Stack&#xff09;和堆&#xff08;Heap&#xff09;是兩種核心內存區域&#xff0c;用于存儲不同類型的數據&#xff0c;它們的設計和存儲規則有明確區分&#xff0c;主要體現在存儲內容、生命周期和管理方式上&#xff1a;一、棧&#xf…

自動駕駛車輛的敏捷安全檔案

簡介近年來&#xff0c;在開發安全關鍵軟件時&#xff0c;敏捷開發方法的使用日益增多。敏捷方法非常適合自動駕駛汽車軟件的增量改進、運行設計域的逐步擴展以及新型智能路側單元的開發。由于車輛和智能路側單元的預期改進&#xff0c;未來幾年將會有新的自動駕駛車輛試驗。因…

【時時三省】(C語言基礎)動態內存分配與它的指針變量

山不在高&#xff0c;有仙則名。水不在深&#xff0c;有龍則靈。 ----CSDN 時時三省什么是內存的動態分配全局變量是分配在內存中的靜態存儲區的&#xff0c;非靜態的局部變量&#xff08;包括形參&#xff09;是分配在內存中的動態存儲區的&#xff0c;這個存儲區是一個稱為棧…

SpringMVC的核心架構與請求處理流程

Spring MVC 核心架構核心組件組件作用類比DispatcherServlet前端控制器&#xff0c;統一接收請求并協調各組件處理一個餐廳的前臺HandlerMapping根據請求URL映射到對應的處理器&#xff08;Controller&#xff09;路由表HandlerAdapter執行處理器方法&#xff0c;處理參數綁定、…

css 不錯的按鈕動畫

效果圖wxml <view class"{{status?active:}}"><view class"up-top btn"><text>向上</text></view><view class"up-left btn"><text>向左</text></view><view class"up-center b…

若依框架RuoYi-Vue-Plus-5.X的啟動,本地安裝docker,再部署 Redis、PG數據庫(智慧水務)SmartWaterServer

一、部署redis數據庫拉取鏡像 docker pull redis啟動Redis容器docker run -d --name redis-server -p 6379:6379 -v redis-data:/data redis redis-server --requirepass 123redis版本二、部署PostgreSQL 數據庫拉取鏡像docker pull postgres:15 創建數據存儲目錄、建議將數據掛…

Idea 清除無用的引用類

在IntelliJ IDEA中&#xff0c;你可以通過以下方式將選中的代碼設置為大寫&#xff1a;1. 使用快捷鍵(推薦)Windows/Linux&#xff1a;Ctrl Shift UMac&#xff1a;Cmd Shift U操作步驟&#xff1a;選中文本按下快捷鍵&#xff0c;即可在大小寫之間切換。2. 通過菜單操作選…

同個主機拉取不同權限倉庫的方法

背景&#xff1a;因為某些神奇的原因&#xff0c;無法同時授權倉庫權限給自己。 1.本地電腦只有權限訪問web倉庫地址&#xff0c;無權限訪問backend倉庫&#xff1b; 2.堡壘機服務器只有權限訪問backend倉庫&#xff0c;無權限訪問web倉庫地址。 web倉庫地址 &#xff1a;codeu…

快速搭建Node.js服務指南

Node.js是構建高效、可擴展網絡應用的理想選擇。以下是幾種快速搭建Node.js服務的方法。 方法一&#xff1a;使用Express&#xff08;最流行框架&#xff09; 1. 初始化項目 mkdir my-node-service cd my-node-service npm init -y2. 安裝Express npm install express3. 基礎服…

通義千問Qwen3-30B-A3B-Thinking-2507技術解析:推理模型的工程實踐突破

Qwen3-30B-A3B模型架構圖2025年7月30日&#xff0c;阿里云通義千問團隊發布了Qwen3-30B-A3B-Thinking-2507推理模型&#xff0c;這是繼Qwen3-30B-A3B-Instruct-2507后的又一力作。作為專注于推理任務的專用模型&#xff0c;它在數學能力測試AIME25上取得85.0分&#xff0c;超越…

【源力覺醒 創作者計劃】文心一言與deepseek集成springboot開發哪個更方便

一.實驗背景 當前文心一言和deepseek都開源了&#xff0c;二者都可以作為大模型應用開發的模型基礎了&#xff0c;我們都可以編寫springboot項目來集成deepseek和文心一言了 二.實驗目標 本文基于實際操作&#xff0c;通過實際操作來對比文心一言和deepseek在集成到springbo…

核磁共振數據T2幾何均值計算

1、T? 幾何均值公式如下&#xff1a;2、核磁T2幾何均值計算代碼 CSV 文件文件格式&#xff1a; 每一行是一個樣點&#xff08;樣品深度&#xff09;&#xff0c;列為&#xff1a;第一列是“深度”或其他&#xff1b;第二列及以后&#xff08;如 TASPEC0 ~ TASPEC199&#xff0…

微服務架構技巧篇——接口類設計技巧

目錄 一、微服務架構的特點 二、微服務接口類設計技巧 2.1、BFF(Backend For Frontend) 2.1.1、 服務分布式帶來的第一個挑戰導致的幾個典型問題 2.1.2、什么是 BFF 2.1.3、BFF 應用場景 2.1.4、BFF 落地經驗 2.1.4.1、前端負責 BFF 開發優缺點 2.1.4.2、后端負責 BFF 開發優…

C++游戲開發(2)

直接上代碼 1.首先是頭文件編寫 #include <iostream> #include <graphics.h> #include <string> 2,添加畫布 長1280&#xff0c;寬720 initgraph(1280, 720); 3.添加主循環 bool running true; while(runing) { } 4.定義結構體變量msg ExMessge msg; 5.開…

Unity開發2D類銀河惡魔城游戲學習筆記目錄

Unity開發2D類銀河惡魔城游戲學習筆記 Unity教程&#xff08;零&#xff09;Unity和VS的使用相關內容 玩家狀態機 Unity教程&#xff08;一&#xff09;開始學習狀態機 Unity教程&#xff08;二&#xff09;角色移動的實現 Unity教程&#xff08;三&#xff09;角色跳躍的實現…

智慧社區項目開發(三)——基于 Spring Boot 實現動態路由加載:從數據庫到前端菜單的完整方案

在后臺管理系統中&#xff0c;不同用戶角色往往擁有不同的操作權限&#xff0c;對應的菜單展示也需動態調整。動態路由加載正是解決這一問題的核心方案 —— 根據登錄用戶的權限&#xff0c;從數據庫查詢其可訪問的菜單&#xff0c;封裝成前端所需的路由結構并返回。本文將詳細…

Python在自動化與運維領域的核心角色:工具化、平臺化與智能化

&#x1f4dd;個人主頁&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的關注 &#x1f339;&#x1f339; 引言 在 IT 系統日益復雜、運維任務持續增長的今天&#xff0c;自動化已成為企業基礎設施管理的關鍵方向。Python 以其簡潔的語法、強大…