springcloud----负载均衡--Ribbon与LoadBalance
簡介
Spring Cloud Ribbon 是 Netflix Ribbon 實現的一套客戶端 負載均衡工具
簡單的說,Ribbon 是 Netflix 發布的開源項目,主要功能是提供 客戶端的復雜均衡算法和服務調用。 Ribbon 客戶端組件提供一系列完善的配置項如超時、重試等。簡單的說,就是配置文件中列出 load Balancer (簡稱 LB)后面所有的機器,Ribbon 會自動的幫助你基于某種規則(如簡單輪詢,隨機鏈接等)去鏈接這些機器。我們很容易使用 Ribbon 自定義的負載均衡算法。
Ribbon官網:https://github.com/Netflix/ribbon
狀態 - 停更進維
替代方案 - Spring Cloud Loadbalancer
功能
LB 負載均衡(Load Balance)是什么
簡單的說就是將用戶的請求平攤的分配到多個服務上,從而達到系統的HA(高可用)
Ribbon 本地負載均衡客戶端 VS Nginx 服務端負載均衡區別
Nginx 是服務器負載均衡,客戶端所有請求都會交給nginx, 然后 nginx 實現轉發請求。即負載均衡是由服務端實現的。
Ribbon 本地負載均衡,在調用微服務接口的時候,會在注冊中心上獲取注冊信息服務列表后緩存到JVM 本地,從而在本地實現RPC遠程 服務調用技術。
LB 實現方式
1、集中式
即在服務的消費方和提供方之間使用獨立的LB 設施(可以是硬件,如F5, 也可以是軟件如 Nginx ), 由該設置負責把訪問請求通過某種策略轉發至服務的提供方
2、進程內 LB
將 LB 邏輯集成到消費方,消費方從服務注冊中心獲取有哪些地址可用,然后自己再從這些地址中選擇一個適合的服務器。
Ribbon 就屬于進程內LB,它只是一個類庫,集成于消費方進程,消費方通過它阿萊獲取服務提供方的地址。
總結:
Ribbon 其實就是一個軟負載均衡的客戶端組件,他可以和其他所需請求的客戶端結合使用,和eureka結合只是其中的一個實例
HA (高可用)
Ribbon 在工作時分為兩步:
第一步先選擇 Server , 它優先選擇在同一個區域呢負載較少的Server
第二步在根據用戶執行的策略,在從server 取到的服務注冊列表中選擇一個地址。
其中 Ribbon 提供了多種策略:比如輪詢、隨機和根據響應時間加權。
(測試使用Eureka做服務注冊 ) 不需要額外導入依賴 ,在 spring-cloud-starter-netflix-eureka-client 自帶 spring-cloud-starter-ribbon
使用方式:@LoadBalance + RestTemplate
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
? ? return ?new RestTemplate() ;
}
1
2
3
4
5
賦予RestTemplate 有負載均衡的能力 也是使用的 ribbon
指定負載均衡的方式
Ribbon 核心組件IRule : com.netflix.loadbalancer.IRule
相關的負載均衡算法 , 均在 com.netflix.loadbalancer 包下
全類名?? ?說明
RoundRobinRule?? ?輪詢
RandomRule?? ?隨機
RetryRule?? ?先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗則在指定時間內會進行重試,獲取可用的服務
WeightedResponseTimeRule?? ?對RoundRobinRule 的拓展,響應速度越快的實例選擇權重越大,越容易被選擇
BestAvailableRule?? ?會先過濾掉由于多次訪問故障而處斷路器跳閘狀態的服務,然后選擇一個并發量最小的服務
AvailabilityFilteringRule?? ?先過濾掉故障實例,在選擇并發較小的實例
ZoneAvoidanceRule?? ?默認規則,符合判斷Server 所在區域的性能和 Server 的可用性選擇服務器
指定負載均衡(在全局Main方法外面建立一個包寫 , 不能讓springboot掃描 , 不然會全局使用該方法)
@Configuration
public class MySelfRule {
? ?@Bean
? ?public IRule myRule(){
? ? ? ?return new RandomRule() ; ?
? ?}
}
1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)?
// 訪問指定服務,使用指定的負載均衡算法
public class OrderMain80 {
? ?public static void main(String[] args){
? ? ? ?SpringApplication.run(OrderMain80.class,args) ;
? ?}
}
1
2
3
4
5
6
7
8
9
自定義負載均衡
負載均衡算法:rest 接口第幾次請求數 % 服務器集群總數量 = 時機調用服務器位置下標,每次服務重啟后rest 接口技術求從1開始。
List<ServiceInstance> instances = discoverClient.getInstances("PAYMENT-SERVICE");
如: ?List[0] instances = 127.0.0.1:8002
? ? ? ? ? List[1] instances = 127.0.0.1:8001
8001 + 8002 組合為集群,他們共計2臺服務器,集群總數為2 , 按照輪詢算法原理:
當請求總數為1 ?時:1%2 = 1, 對應下標位置為1, 則獲得服務地址為 127.0.0.1:8001
當請求總數為2 時:2%2 = 0, 對應下標位置為1, 則獲得服務地址為 127.0.0.1:8002
當請求總數為3 時:2%2 = 1, 對應下標位置為1, 則獲得服務地址為 127.0.0.1:8001
依次類推 。。。。
1
2
3
4
5
6
7
8
9
10
11
12
1、接口
public interface LandBalance {
? ? ServiceInstance instance(List<ServiceInstance> serviceInstances) ;
}
1
2
3
2、實現
@Component
public class MyLb implements LandBalance {
? ? // 原子類
? ? private AtomicInteger atomicInteger = new AtomicInteger(0) ;
? ? public final int getAndIncrement(){
// ? ? ? ?自旋鎖
? ? ? ? int current ;
? ? ? ? int next ;
? ? ? ? do {
? ? ? ? ? ? current = this.atomicInteger.get() ;
? ? ? ? ? ? next = current >= 2147483647 ? 0 : current + 1 ;
? ? ? ? }while (!this.atomicInteger.compareAndSet(current ,next )) ;
? ? ? ? System.out.println("****訪問次數 next: "+ next );
? ? ? ? return next ;
? ? }
? ? @Override
? ? public ServiceInstance instance(List<ServiceInstance> serviceInstances) {
? ? ? ? int index = ?getAndIncrement() % serviceInstances.size() ;
? ? ? ? return serviceInstances.get(index) ;
? ? }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
3、使用 (restTemplate 上不能有 LoadBalance注解)
@Autowired
private LandBalance landBalance ;
@Autowired
DiscoveryClient discoveryClient ;
? ??
@GetMapping("/consumer/payment/lb")
public String getPaymentLb(){
? ? List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
? ? if (instances == null || instances.size() <= 0 ){
? ? ? ? return ?null ;
? ? }
? ? ServiceInstance instance = landBalance.instance(instances);
? ? URI uri = instance.getUri();
? ?return restTemplate.getForObject(uri+"/payment/lb",String.class) ;
}
————————————————
版權聲明:本文為CSDN博主「千鈞~」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/getchar97/article/details/105083324
總結
以上是生活随笔為你收集整理的springcloud----负载均衡--Ribbon与LoadBalance的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 月薪两万为什么在老乡鸡只能点三个肉菜?
- 下一篇: 茭白家常做法?