目錄
一、Ribbon目前也進入維護模式
二、spring-cloud-loadbalancer概述
三、spring-cloud-loadbalancer負載均衡解析
1.負載均衡演示案例-理論
2.負載均衡演示案例-實操
按照8001拷貝后新建8002微服務
啟動Consul,將8001/8002啟動后注冊進微服務
Consul數據持久化配置并且注冊為Windows服務
方式一:編寫腳本的方式
方式二:通過-data-dir進行設置consul持久化目錄
消費者-訂單80模塊修改POM并注冊進consul,新增LoadBalancer組件
訂單80模塊修改Controler并啟動80
目前consul上的服務 將order也進行注冊
測試
3.負載均衡演示案例-小總結?
編碼使用DiscoveryClient動態獲取所有上線的服務列表
代碼解釋,修改80微服務的Controller
結合前面實操,負載選擇原理小總結
4.負載均衡算法原理
官網算法
默認算法
算法切換
測試
一、Ribbon目前也進入維護模式
Spring Cloud Ribbon是基于Netflix Ribbon實現的一套 客戶端 負載均衡的工具。簡單的說,Ribbon是Netflix發布的開源項目,主要功能是 提供客戶端的軟件負載均衡算法和服務調用。Ribbon客戶端組件提供一系列完善的配置項如連接超時,重試等。簡單的說,就是在配置文件中列出Load Balancer(簡稱LB)后面所有的機器,Ribbon會自動的幫助你基于某種規則(如簡單輪詢,隨機連接等)去連接這些機器。我們很容易使用Ribbon實現自定義的負載均衡算法。
項目狀態:維護中...


二、spring-cloud-loadbalancer概述
loadbalancer目前在springcloudcommons下


簡單的說就是將用戶的請求平攤的分配到多個服務上,從而達到系統的HA(高可用),常見的負載均衡有軟件Nginx,LVS,硬件 F5等
Spring Cloud LoadBalancer是由SpringCloud官方提供的一個開源的、簡單易用的 客戶端負載均衡器,它包含在SpringCloud-commons中用它來替換了以前的Ribbon組件。相比較于Ribbon,SpringCloud LoadBalancer不僅能夠支持RestTemplate,還支持WebClient(WeClient是Spring Web Flux中提供的功能,可以實現響應式異步請求)
Nginx是 服務器負載均衡,客戶端所有請求都會交給nginx,然后由nginx實現轉發請求,即負載均衡是由服務端實現的。?loadbalancer 本地負載均衡,在調用微服務接口時候,會在注冊中心上獲取注冊信息服務列表之后緩存到JVM本地,從而在本地實現RPC遠程服務調用技術。
三、spring-cloud-loadbalancer負載均衡解析
1.負載均衡演示案例-理論

第一步,先選擇ConsulServer從服務端查詢并拉取服務列表,知道了它有多個服務(上圖3個服務),這3個實現是完全一樣的,默認輪詢調用誰都可以正常執行。類似生活中求醫掛號,某個科室今日出診的全部醫生,客戶端你自己選一個。第二步,按照指定的負載均衡策略從server取到的服務注冊列表中由客戶端自己選擇一個地址,所以LoadBalancer是一個 客戶端的 負載均衡器。
2.負載均衡演示案例-實操


按照8001拷貝后新建8002微服務
啟動Consul,將8001/8002啟動后注冊進微服務
看到兩個service已注冊成功, 但是consul的key/value之前配置未進行持久化保存,已經不存在

Consul數據持久化配置并且注冊為Windows服務
方式一:編寫腳本的方式
- 新建mydata文件夾
- 新建文件consul start.bat后綴為.bat
@echo.服務啟動......
@echo off
@sc create Consul binpath= "D:\devSoft\consul_1.17.0_windows_386\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect 1 -data-dir D:\devSoft\consul_1.17.0_windows_386\mydata "
@net start Consul
@sc config Consul start= AUTO
@echo.Consul start is OK......success
@pause



方式二:通過-data-dir進行設置consul持久化目錄
consul agent -server -config-dir=E:/consul/config -data-dir=E:/consul/data -bind=127.0.0.1 -bootstrap-expect=1 -ui
-consul agent:啟動Consul的代理(agent)進程。Consul代理是Consul服務的核心組件,負責服務注冊與發現、健康檢查、鍵值存儲等功能。-server:指定此Consul代理以服務器模式運行。在服務器模式下,該代理將參與Raft一致性協議,能夠處理集群的選舉、日志復制等任務,是Consul集群中不可或缺的一部分。-config-dir=E:/consul/config:指定一個目錄,Consul會從該目錄中加載額外的配置文件。這些配置文件可以是JSON或HCL格式,用于自定義Consul的行為,如服務定義、ACL策略等。-data-dir=E:/consul/data:指定一個目錄,Consul將在此目錄中存儲其運行所需的數據,包括服務注冊信息、健康檢查的狀態、鍵值存儲的數據以及Raft日志和快照等。這個目錄對于Consul的數據持久化至關重要。-bind=127.0.0.1:指定Consul代理綁定的IP地址。在這個例子中,Consul被配置為僅監聽本地回環地址(127.0.0.1),這意味著它不會接受來自外部網絡的連接請求,增強了安全性。這通常用于開發或測試環境。-bootstrap-expect=1:這是一個引導模式配置,指定了Consul期望在集群中看到的服務器節點數。在這個例子中,-bootstrap-expect=1 表示這是一個單節點集群的配置。由于集群中只有一個節點,Consul將立即進入領導者模式,無需等待其他節點的加入。-ui:啟用Consul的內置Web UI。通過Web UI,用戶可以方便地查看和管理Consul集群的狀態,包括服務列表、健康檢查、鍵值對等。
- cloud-payment-service-8001:http://localhost:8001/pay/get/info
- cloud-payment-service-8002:http://localhost:8002/pay/get/info

消費者-訂單80模塊修改POM并注冊進consul,新增LoadBalancer組件

<!--loadbalancer-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
訂單80模塊修改Controler并啟動80
cloud-payment-service 要與consul上注冊名稱一致。
@RestController
public class OrderController
{//public static final String PaymentSrv_URL = "http://localhost:8001";//先寫死,硬編碼public static final String PaymentSrv_URL = "http://cloud-payment-service";//服務注冊中心上的微服務名稱@Autowiredprivate RestTemplate restTemplate;/*** 一般情況下,通過瀏覽器的地址欄輸入url,發送的只能是get請求* 我們模擬消費者發送get請求,but底層調用post方法,客戶端消費者參數PayDTO可以不添加@RequestBody* @param payDTO* @return*/@GetMapping("/consumer/pay/add")public ResultData addOrder(PayDTO payDTO){return restTemplate.postForObject(PaymentSrv_URL + "/pay/add",payDTO,ResultData.class);}@GetMapping("/consumer/pay/get/{id}")public ResultData getPayInfo(@PathVariable Integer id){return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+id, ResultData.class, id);}@GetMapping(value = "/consumer/pay/get/info")private String getInfoByConsul(){return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/info", String.class);}
}
目前consul上的服務 將order也進行注冊

測試


3.負載均衡演示案例-小總結?
編碼使用DiscoveryClient動態獲取所有上線的服務列表

代碼解釋,修改80微服務的Controller
@Resource
private DiscoveryClient discoveryClient;
@GetMapping("/consumer/discovery")
public String discovery()
{List<String> services = discoveryClient.getServices();for (String element : services) {System.out.println(element);}System.out.println("===================================");List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");for (ServiceInstance element : instances) {System.out.println(element.getServiceId()+"\t"+element.getHost()+"\t"+element.getPort()+"\t"+element.getUri());}return instances.get(0).getServiceId()+":"+instances.get(0).getPort();
}
DiscoveryClient獲取所有上線的服務列表數據:
cloud-consumer-order
cloud-payment-service
consul
cloud-payment-service? ? WIN-C38UV4TIS4J 8001? ? ?http://WIN-C38UV4TIS4J:8001
cloud-payment-service? ? WIN-C38UV4TIS4J 8002 ? ? http://WIN-C38UV4TIS4J:8002
結合前面實操,負載選擇原理小總結
負載均衡算法:rest接口第幾次請求數 % 服務器集群總數量 = 實際調用服務器位置下標 ,每次服務重啟動后rest接口計數從1開始。List instances = discoveryClient.getInstances("cloud-payment-service");如: List [0] instances = 127.0.0.1:8002List [1] instances = 127.0.0.1:80018001+ 8002 組合成為集群,它們共計2臺機器,集群總數為2, 按照輪詢算法原理:當總請求數為1時: 1 % 2 =1 對應下標位置為1 ,則獲得服務地址為127.0.0.1:8001當總請求數位2時: 2 % 2 =0 對應下標位置為0 ,則獲得服務地址為127.0.0.1:8002當總請求數位3時: 3 % 2 =1 對應下標位置為1 ,則獲得服務地址為127.0.0.1:8001當總請求數位4時: 4 % 2 =0 對應下標位置為0 ,則獲得服務地址為127.0.0.1:8002如此類推......
4.負載均衡算法原理
官網算法
默認算法
默認兩種算法輪詢和隨機

public class RoundRobinLoadBalancer implementsReactorServiceInstanceLoadBalancer
public class RandomLoadBalancer implementsReactorServiceInstanceLoadBalancer
主要用于配置和定制特定的客戶端負載均衡器行為。@LoadBalancerClient 可以用來為特定的微服務配置負載均衡器的相關設置。通過指定name或value屬性(兩者通常可以互換使用),你可以指定一個服務的ID,該ID與Spring Cloud consul(或其他服務注冊中心)中注冊的服務名相對應。這樣,你就 可以為特定的服務定制負載均衡策略、重試機制等。在微服務架構中,不同的服務可能需要不同的負載均衡配置。@LoadBalancerClient 允許你通過為不同的服務定義不同的配置類來實現 配置的隔離。這樣, 每個服務都可以根據自身的需求來定制負載均衡行為,而不會影響到其他服務。還允許你通過configuration屬性來指定一個配置類,該配置類中可以定義 自定義的負載均衡器、規則、攔截器等。
算法切換
從默認的輪詢,切換為 隨機算法,修改RestTemplateConfig
/*** LoadBalancer默認輪詢算法切換隨機算法* @LoadBalancerClient @Bean*/
@Configuration
@LoadBalancerClient(//下面的value值大小寫一定要和consul里面的名字一樣,必須一樣value = "cloud-payment-service",configuration = RestTemplateConfig.class)
public class RestTemplateConfig
{@Bean@LoadBalanced //使用@LoadBalanced注解賦予RestTemplate負載均衡的能力public RestTemplate restTemplate(){return new RestTemplate();}@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
@LoadBalancerClient(name = "my-service", configuration = MyServiceLoadBalancerConfig.class)
public class MyServiceConfiguration { // 這里可以包含一些針對my-service的特定配置
} @Configuration
public class MyServiceLoadBalancerConfig { @Bean public IRule myCustomRule() { // 返回一個自定義的負載均衡規則 return new MyCustomRule(); }
}
測試
測試地址: http://localhost/consumer/pay/get/info實現效果:隨機訪問cloud-payment-service服務