国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring Cloud系列】- Ribbon詳解與實戰(zhàn)

這篇具有很好參考價值的文章主要介紹了【Spring Cloud系列】- Ribbon詳解與實戰(zhàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【Spring Cloud系列】- Ribbon詳解與實戰(zhàn)


在前面的文章 Eureka詳解與實戰(zhàn)、Eureka Client應用、RestTemplate詳解及其負載均衡幾篇文章中,已經介紹了Spring Cloud基本應用,本文將從講解在進程層面的負載均衡,在Spring Cloud中如何使用Ribbon做系統(tǒng)應用層面的負載均衡使用。

一、什么是Ribbon

Ribbon是netflix 公司開源的基于客戶端的負載均衡組件,是Spring Cloud大家庭中非常重要的一個模塊;Ribbon應該也是整個大家庭中相對而言比較復雜的模塊,直接影響到服務調度的質量和性能。全面掌握Ribbon可以幫助我們了解在分布式微服務集群工作模式下,服務調度應該考慮到的每個環(huán)節(jié)。

Ribbon內部提供了一個接口叫做ILoadBalance的接口代表負載均衡器的操作,這個接口包含添加服務器操作、選擇服務器操作、獲取所有的服務器列表、獲取可用服務器列表等功能。

下圖展示Ribbon的架構圖

【Spring Cloud系列】- Ribbon詳解與實戰(zhàn),Spring Cloud,spring cloud,ribbon,spring

二、Spring Cloud中Ribbon應用

Ribbon使用步驟如下

  1. 在Eureka Client中添加bom.xml 依賴

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    
  2. RestTemplate配置類添加@LoadBalanced注解

    @Configuration
    public class RestTemplateConfig {
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }
    
  3. 啟動類添加注解@EnableEurekaClient和@RibbonClient(name = “Eureka中spring.application.name”)

    @SpringBootApplication
    @EnableEurekaClient
    @RibbonClient(name="GoyeerRibbonDemo")
    public class GoyeerCloudRibbonAppliction {
        public static void main(String[] args){
            SpringApplication.run(GoyeerCloudRibbonAppliction.class);
        }
    }
    
  4. application.yml配置內容

    server:
      port: 8081
    eureka:
      client:
        service-url:
          defaultZone: http://server30000:30000/eureka/,http://server30001:30001/eureka/,http://server30002:30002/eureka/
        register-with-eureka: false
    spring:
      application:
        name: GoyeerRibbon
      profiles:
        active: ribbonClient
    
  5. 編寫控制器

     @Autowired
     private  RestTemplateConfig restTemplateConfig;
     @RequestMapping(value = "/")
     public String index(){
            String url="http://GOYEERBOM"; //注冊Eureka中的服務名
            RestTemplate restTemplate=restTemplateConfig.getRestTemplate();
            String str=restTemplate.getForObject(url,String.class);
            return str;
     }
    
  6. 服務端效果

    • Eureka服務器端
      【Spring Cloud系列】- Ribbon詳解與實戰(zhàn),Spring Cloud,spring cloud,ribbon,spring

    • Ribbon調用后結構

三、Ribbon負載均衡策略設置

3.1 全局策略設置

/**
 * @Author:Goyeer
 * @Description:Ribbon 全局的負載均衡策略配置類
 * @CreateDate:2023-07-11
 */
@Configuration
public class RibbonGlobalLoadBalancingConfiguration {
    /**
     * 隨機規(guī)則
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }

}

3.2 基于注解的針對單個服務的 Ribbon 負載均衡策略

3.2.1 注解方式
/**
 * @Author:Goyeer
 * @Description:Ribbon 隨機負載均衡策略配置類哪個服務引用就作用在那個服務上面在啟動類上方使用 @RibbonClient 引用
 * @CreateDate:2023-07-11
 */
@Configuration
@AvoidScan
public class RibbonRandomLoadBalancingConfiguration {
    @Resource
    IClientConfig clientConfig;
    @Bean
    public IRule ribbonRule(IClientConfig clientConfig) {
        return new RandomRule();
    }
}
3.2.2 IClientConfig針對客戶端的配置管理器
/** 配置針對單個服務的 Ribbon 負載均衡策略 **/
@RibbonClient(
        name = "goyeer-balance-ribbon", configuration = RibbonRandomLoadBalancingConfiguration.class
)
/** 此處配置根據標識 @AvoidScan 過濾掉需要單獨配置的 Ribbon 負載均衡策略,不然就會作用于全局,啟動就會報錯 */
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = AvoidScan.class)
)

3.3 配置文件方式

### 針對單個服務的 Ribbon 配置
goyeer-balance-ribbon:
  ribbon:
    # 基于配置文件形式的 針對單個服務的 Ribbon 負載均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

四、如何自定義Ribbon負載均衡策略

4.1 自定義算法

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import org.springframework.stereotype.Component;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class RandomRule_ZY extends AbstractLoadBalancerRule {
    //定義一個原子類,以保證原子性
    private AtomicInteger atomicInteger =new AtomicInteger(0);
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null){
            return null;
        }
        //用于統(tǒng)計獲取次數(shù),當達到一定數(shù)量就不再去嘗試
        int count = 0;
        Server server = null;
        //當服務還沒獲取到,并且嘗試沒有超過8次
        while (server == null && count++ < 8){
            //獲取服務
            List<Server> allServers = lb.getAllServers();
            List<Server> reachableServers = lb.getReachableServers();
            int allServersSize = allServers.size();
            int reachableServersSize = reachableServers.size();
            //如果獲取的服務list都為0就返回null
            if(allServersSize == 0 || reachableServersSize == 0){
                return  null;
            }
            //獲取服務下標
            int next = getServerIndex(allServersSize);
            //獲取服務
            server = reachableServers.get(next);
            //如果服務為空直接跳過下面的
            if (server == null){
                continue;
            }
            //如果獲取到的這個服務是活著的就返回
            if (server.isAlive()){
                return server;
            }
            //如果獲取到的服務不是空,但是不是存活狀態(tài),需要重新獲取
            server=null;
        }
        //最后這里可能會返回null
        return  server;
    }
    //獲取服務下標,為了保證原子性,使用了CAS
    public int getServerIndex(int allServersSize){
        //自旋鎖
        for (;;) {
            //獲取當前值
            int current = this.atomicInteger.get();
            //設置期望值
            int next = (current + 1) % allServersSize;
            //調用Native方法compareAndSet,執(zhí)行CAS操作
            if (this.atomicInteger.compareAndSet(current, next))
                //成功后才會返回期望值,否則無線循環(huán)
                return next;
        }
    }
    public Server choose(Object key) {
        return choose(getLoadBalancer(),key);
    }
}

4.2 自定義配置類

@Configuration
//針對全局修改
//@RibbonClients(defaultConfiguration = MyRuleConfig.class)
//針對某個服務修改
@RibbonClient(name = "nacos-app-a", configuration = MyRuleConfig.class)
public class MyRuleConfig {
    @Bean
    public IRule rule() {
      //返回上面自定義的規(guī)則類
        return new RandomRule_ZY();
    }
}

4.3 設置加載自定義Ribbon配置類

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "Client",configuration = MyRuleConfig.class)
public class GoyeerCloudRibbonAppliction {
    public static void main(String[] args){
        SpringApplication.run(GoyeerCloudRibbonAppliction.class);
    }
}

五、LoadBalancer–負載均衡器的核心

Ribbon實現(xiàn)負載均衡是通過LoadBalancer注解來給RestTemplate標記,來實現(xiàn)負載均衡。LoadBalancer是如何實現(xiàn)負載均衡哪?查看源碼我們可以看到有一個接口LoadBalancerClinet來實現(xiàn)的。

5.1 什么是LoadBalancerClient

LoadBalancerClient 是 SpringCloud 提供的一種負載均衡客戶端,Ribbon 負載均衡組件內部也是集成了 LoadBalancerClient 來實現(xiàn)負載均衡。

5.2 LoadBalancerClient原理

LoadBalancerClinet在初始化時會通過Euraka Clinet向Eureka服務端獲取所有的服務實例的注冊信息并緩存到本地,并且每10秒向EurakaClinet發(fā)送“Ping”請求,來判斷服務的可用性。如果服務的可用性發(fā)生了改變或者服務數(shù)量和之前的不一致,則更新或重新拉取最新到本地。在得到最新服務注冊信息后,ILoadBalancer根據IRule的策略進行負載均衡(默認策略為輪詢)。

當使用LoadBalancerClient進行遠程調用的負載均衡時,LoadBalancerClient先通過目標服務名在本地服務注冊清單中獲取服務提供方的某個實例,如多個服務器節(jié)點,LoadBalancerClient會通過choose()方法獲取到多個節(jié)點中一個服務,拿到服務的信息之后取出服務IP信息,就可以得到完整的想要訪問的IP地址和端口號,最后通過RestTempate訪問具體的服務信息。

5.3 LoadBabancerClient源碼解析

5.3.1 LoadBalancerClient 類圖

LoadBalancerClient 是 Spring Cloud 提供的一個非常重要的接口,它繼承ServiceInstanceChooser 接口,該接口的實現(xiàn)類是 RibbonLoadBalanceClient,它們之間的關系如下圖所示:

5.3.2 LoadBalancerClient 接口源碼
public interface LoadBalancerClient extends ServiceInstanceChooser 
{
	<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
     
    <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
    
    URI reconstructURI(ServiceInstance instance, URI original);
}

可以發(fā)現(xiàn) LoadBalancerClient 接口繼承了 ServiceInstanceChooser 接口,包含兩個方法:executereconstructURI

  • execute() 用來執(zhí)行Request請求
  • reconstructURI() 用來重構URL
5.3.3 ServiceInstanceChooser 接口源碼
public interface ServiceInstanceChooser 
{
	ServiceInstance choose(String serviceId);
}

ServiceInstanceChooser 接口中的主要方法為 choose(),該方法用于根據服務的名稱 serviceId 來選擇其中一個服務實例,即根據 serviceId 獲取ServiceInstance。

5.3.4 RibbonLoadBalanceClient 實現(xiàn)類源碼

LoadBalancerClient 的實現(xiàn)類 RibbonLoadBalanceClient,它用來執(zhí)行最終的負載均衡請求。其中,RibbonLoadBalanceClient 的一個 choose() 方法用于選擇具體的服務實例,其內部是通過 getServer() 方法交給 ILoadBalancer 完成的。

  • choose(),用來選擇具體的服務實例
    @Override
    public ServiceInstance choose(String serviceId) {
    	return choose(serviceId, null);
    }
     
    /**
     * New: Select a server using a 'key'.
     * @param serviceId of the service to choose an instance for
     * @param hint to specify the service instance
     * @return the selected {@link ServiceInstance}
     */
    public ServiceInstance choose(String serviceId, Object hint) {
      Server server = getServer(getLoadBalancer(serviceId), hint);
      if (server == null) {
    	 return null;
      }
      return new RibbonServer(serviceId, server, isSecure(server, serviceId),serverIntrospector(serviceId).getMetadata(server));
    }
    
  • getServer(),獲取實例
    protected Server getServer(ILoadBalancer loadBalancer) {
       return getServer(loadBalancer, null);
    }
    protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
       if (loadBalancer == null) {
    	   return null;
       }
       // 最終通過 loadBalancer 去做服務實例的選擇。
       // Use 'default' on a null hint, or just pass it on?
       return loadBalancer.chooseServer(hint != null ? hint : "default");
    }
    
5.3.5 BaseLoadBalancer 源碼
5.3.6 IRule 接口源碼
public interface IRule{ 
    public Server choose(Object key);
    public void setLoadBalancer(ILoadBalancer lb);
    public ILoadBalancer getLoadBalancer();    
}

IRule 接口定義了3個方法,分別是:choosesetLoadBalancergetLoadBalancer

  • choose() 是用來選擇實例的
  • setLoadBalancer()用來設置負載均衡規(guī)則
  • getLoadBalancer()獲取負載均衡規(guī)則

實現(xiàn)IRule有個類,分別定義不同的負載均衡規(guī)則:

  • 隨機策略 RandomRule
  • 輪詢策略 RoundRobinRule
  • 重試策略 RetryRule
  • 可用過濾策略 PredicateBaseRule
  • 響應時間權重策略 WeightedRespinseTimeRule
  • 并發(fā)量最小可用策略 BestAvailableRule
  • 區(qū)域權重策略 ZoneAvoidanceRule
5.3.7 ILoadBalancer 源碼

ILoadBalancer 是一個接口,該接口定義了一系列實現(xiàn)負載均衡的方法,LoadBalancerClient 的實現(xiàn)類 RibbonLoadBalanceClient 也將負載均衡的具體實現(xiàn)交給了 ILoadBalancer 來處理,ILoadBalancer 通過配置 IRule、IPing 等,向 EurekaClient 獲取注冊列表信息,默認每10秒向 EurekaClient 發(fā)送一次 “ping”,進而檢查是否需要更新服務的注冊列表信息。最后,在得到服務注冊列表信息后,ILoadBalancer 根據 IRule 的策略進行負載均衡。

查看 BaseLoadBalancer 和 DynamicServerListLoadBalancer 源碼,默認情況下實現(xiàn)了以下配置:

  1. IClientConfig clientConfig:用于配置負載均衡客戶端,默認實現(xiàn)類是 DefaultClientConfigImpl。
  2. IRule rule:用于配置負載均衡的策略,默認使用的是 RoundRobinRule 輪詢策略。
  3. IPing ping:用于檢查當前服務是否有響應,從而判斷當前服務是否可用,默認實現(xiàn)類是 DummyPing,該實現(xiàn)類的 isAlive() 方法返回值是 true,默認所有服務實例都是可用的。
  4. ServerList serverList:用于獲取所有 Server 注冊列表信息。通過跟蹤源碼會發(fā)現(xiàn),ServerList 的實現(xiàn)類是 DiscoveryEnabledNIWSServerList,該類定義的 obtainServersViaDiscovery() 方法是根據 eurekaClientProvider.get() 方法獲取 EurekaClient,再根據 EurekaClient 獲取服務注冊列表信息。EurekaClient 的實現(xiàn)類是DiscoveryClient,DiscoveryClient 具有服務注冊、獲取服務注冊列表等功能。
  5. ServerListFilter filter:定義了根據配置過濾或者動態(tài)獲取符合條件的服務列表,默認實現(xiàn)類是 ZonePreferenceServerListFilter,該策略能夠優(yōu)先過濾出與請求調用方處于同區(qū)域的服務實例。

六、Ribbon的配置參數(shù)

控制參數(shù) 說明 默認值
<service-name>.ribbon.NFLoadBalancerPingInterval Ping定時任務周期 30s
service-name>.ribbon.NFLoadBalancerMaxTotalPingTime Ping超時時間 2s
<service-name>.ribbon.NFLoadBalancerRuleClassName IRule實現(xiàn)類 RoundRobinRule,基于輪詢調度算法規(guī)則選擇服務實例
<service-name>.ribbon.NFLoadBalancerPingClassName IPing實現(xiàn)類 DummyPing,直接返回true
<service-name>.ribbon.NFLoadBalancerClassName 負載均衡器實現(xiàn)類 2s
<service-name>.ribbon.NIWSServerListClassName ServerList實現(xiàn)類 ConfigurationBasedServerList,基于配置的服務列表
<service-name>.ribbon.ServerListUpdaterClassName 服務列表更新類 PollingServerListUpdater
<service-name>.ribbon.NIWSServerListFilterClassName 服務實例過濾器 2s
<service-name>.ribbon.NIWSServerListFilterClassName 服務實例過濾器 2s
<service-name>.ribbon.ServerListRefreshInterval 服務列表刷新頻率 2s
<service-name>.ribbon.NFLoadBalancerClassName 自定義負載均衡器實現(xiàn)類 2s

七、總結

Ribbon是Spring cloud的核心,負載微服務內負載調用;Ribbon可以脫離Spring Cloud的單獨使用。

Ribbon是微服務整個微服務組件最復雜的一環(huán),控制流程上為保證服務的高可用性,有比較多的細節(jié)參數(shù)控制,在使用的過程中需要深入理清每個環(huán)節(jié)的處理機制,使之發(fā)揮穩(wěn)定且高效的作用。文章來源地址http://www.zghlxwxcb.cn/news/detail-553994.html

到了這里,關于【Spring Cloud系列】- Ribbon詳解與實戰(zhàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Spring Cloud學習筆記(Ribbon):Ribbon的應用樣例

    Spring Cloud學習筆記(Ribbon):Ribbon的應用樣例

    這是本人學習的總結,主要學習資料如下 - 馬士兵教育 我們都知道 Ribbon 是用于負載均衡的。提供同一種服務的 Client 可能有多個,比如有多個 User Client 提供查詢用戶信息的服務,使用 Ribbon 就能簡單地達到負載均衡的效果。 想要使用 Ribbon ,無論是服務提供者還是調用服務

    2024年04月25日
    瀏覽(19)
  • Spring Cloud Ribbon:負載均衡

    1. 介紹 Spring Cloud Ribbon 1.1 什么是 Spring Cloud Ribbon Spring Cloud Ribbon是Netflix開源的負載均衡器,它為分布式服務提供了客戶端負載均衡的功能。Ribbon可以根據一系列的負載均衡算法和配置策略,將客戶端的請求動態(tài)分發(fā)到多個服務實例上,以實現(xiàn)高可用性和性能優(yōu)化。 1.2 負載均

    2024年02月19日
    瀏覽(22)
  • 【Spring Cloud 四】Ribbon負載均衡

    【Spring Cloud 四】Ribbon負載均衡

    【Spring Cloud一】微服務基本知識 【Spring Cloud 三】Eureka服務注冊與服務發(fā)現(xiàn) 目前公司項目使用的注冊中心主要是Spring Cloud Alibaba的Nacos做的注冊中心和配置中心。并且Nacos使用了Ribbon作為默認的負載均衡器。但是相當于將Ribbon的負載均衡給透明化了,日常開發(fā)明面上是看不到

    2024年02月14日
    瀏覽(27)
  • Spring Cloud之負載均衡與服務調用(Ribbon)

    Spring Cloud之負載均衡與服務調用(Ribbon)

    目錄 Ribbon 簡介 負載均衡 簡介 負載均衡方式 服務端負載均衡 工作原理 特點 客戶端負載均衡 工作原理 特點 對比 實現(xiàn) 負載均衡策略 切換負載均衡策略 定制負載均衡策略 超時與重試 單個服務配置 全局配置 服務調用 示例 ????????Ribbon 是 Netflix 公司發(fā)布的開源組件,其

    2024年02月08日
    瀏覽(19)
  • Ribbon:Spring Cloud負載均衡與服務調用組件

    Ribbon:Spring Cloud負載均衡與服務調用組件

    負載均衡? Ribbon實現(xiàn)服務調用? Ribbon實現(xiàn)負載均衡? 切換負載均衡策略? 定制負載均衡策略? 負載均衡 負載均衡(Load Balance),將用戶的請求平分到多個服務器上運行,以擴展服務器帶寬、增強數(shù)據處理能力、增加吞吐量、提高網絡的可用性和靈活性的目的。 服務端負載

    2024年02月03日
    瀏覽(29)
  • 【Spring Cloud】Nacos及Ribbon組件的使用

    【Spring Cloud】Nacos及Ribbon組件的使用

    ????歡迎來到我的CSDN主頁!???? ??我是Java方文山,一個在CSDN分享筆記的博主。???? ??推薦給大家我的專欄《Spring Cloud》。???? ??點擊這里,就可以查看我的主頁啦!???? Java方文山的個人主頁 ??如果感覺還不錯的話請給我點贊吧!???? ??期待你的加入,一起

    2024年01月25日
    瀏覽(19)
  • 【Spring Cloud】Ribbon 中的幾種負載均衡策略

    【Spring Cloud】Ribbon 中的幾種負載均衡策略

    負載均衡通常有兩種實現(xiàn)手段,一種是服務端負載均衡器,另一種是客戶端負載均衡器,而我們今天的主角 Ribbon 就屬于后者——客戶端負載均衡器。 服務端負載均衡器的問題是,它提供了更強的流量控制權,但無法滿足不同的消費者希望使用不同負載均衡策略的需求,而使

    2024年02月15日
    瀏覽(27)
  • Spring Cloud - Ribbon 負載均衡原理、負載策略、懶加載

    Spring Cloud - Ribbon 負載均衡原理、負載策略、懶加載

    目錄 ?編輯 一、Ribbon 負載均衡原理 1.1、前言 1.2、負載均衡的工作流程 二、負載均衡策略 2.1、策略原理 2.2、負載均衡自定義方式 三、Ribbon 加載方式 ps:案例是上一章所講的?“根據訂單id查詢訂單的同時,把訂單所屬的用戶信息一起返回”? 。 上一章我們講到 order-servi

    2024年02月09日
    瀏覽(23)
  • Spring Boot 中的 Spring Cloud Ribbon:什么是它,原理及如何使用

    Spring Boot 中的 Spring Cloud Ribbon:什么是它,原理及如何使用

    在分布式系統(tǒng)中,服務之間的通信是非常重要的。在大型的分布式系統(tǒng)中,有許多服務需要相互通信,而這些服務可能會部署在多個服務器上。為了實現(xiàn)服務之間的通信,開發(fā)人員需要編寫大量的代碼來處理負載均衡、故障轉移和服務發(fā)現(xiàn)等問題。為了簡化這個過程,Spring

    2024年02月12日
    瀏覽(18)
  • 【Spring Cloud】Ribbon 實現(xiàn)負載均衡的原理,策略以及饑餓加載

    【Spring Cloud】Ribbon 實現(xiàn)負載均衡的原理,策略以及饑餓加載

    在前文《深入理解 Eureka 注冊中心的原理、服務的注冊與發(fā)現(xiàn)》中,介紹了如何使用 Eureka 實現(xiàn)服務的注冊與拉取,并且通過添加 @LoadBalanced 注解實現(xiàn)了負載均衡。這種自動化的背后隱藏著許多疑問: 服務是在何時進行拉取的? 負載均衡是如何實現(xiàn)的? 負載均衡的原理和策略

    2024年02月07日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包