天天看點

SpringCloud系列八:自定義Ribbon配置

1. 回顧

  上文使用Ribbon實作了用戶端側的負載均衡。但是很多場景下,我們可能需要自定義Ribbon的配置,比如修改Ribbon的負載均衡規則。

  Spring Cloud允許使用Java代碼或屬性自定義Ribbon的配置,這兩種方式是等價的。

  在Spring Cloud中,Ribbon的預設配置如下(格式是BeanType beanName:ClassName):

  • IClientConfig ribbonClientConfig:DefaultClientConfigImpl
  • IRule ribbonRule:ZoneAvoidanceRule
  • IPing ribbonPing:NoOpPing
  • ServerList ribbonServerList:ConfigurationBasedServerList
  • ServerListFilter ribbonServerListFilter:ZonePreferenceServerListFilter
  • ILoadBalance ribbonLoadBalancer:ZoneAwareLoadBalancer
@Bean
@ConditionalOnMissingBean
public IRule ribbonRule(IClientConfig config) {
    if (this.propertiesFactory.isSet(IRule.class, this.name)) {
        return (IRule)this.propertiesFactory.get(IRule.class, config, this.name);
    } else {
        ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
        rule.initWithNiwsConfig(config);
        return rule;
    }
}
// 來自 org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration      

   BeanType是IRule,beanName是ribbonRule,ClassName是ZoneAvoidanceRule,這是一種根據服務提供者所在Zone的性能以及

  服務提供者可用性綜合計算,選擇提供者節點的負載均衡規則。

  在Spring Cloud中, Ribbon預設的配置類是RibbonClientConfiguration。也可使用一個POJO自定義Ribbon的配置(自定義配置會覆寫預設配置)。

  這種配置是細粒度的,不同的Ribbon用戶端可以使用不同的配置。

2. 使用Java代碼自定義Ribbon配置

  > 複制項目 microservice-consumer-movie-ribbon,将ArtifactId修改為 microservice-consumer-movie-ribbon-customizing

  > 建立一個注解類

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing.annotation;

public @interface ExcludeComponent {
}      

  > 修改啟動類,使@CompantScan不掃描被自定義注解注解的類

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
        value = {com.itmuch.cloud.microserviceconsumermovieribboncustomizing.annotation.ExcludeComponent.class}))
public class MicroserviceConsumerMovieRibbonCustomizingApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceConsumerMovieRibbonCustomizingApplication.class, args);
    }

    @Bean
    @LoadBalanced // 實作負載均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}      

  > 建立Ribbon的配置類

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing.config;

import com.itmuch.cloud.microserviceconsumermovieribboncustomizing.annotation.ExcludeComponent;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 該類為Ribbon的配置類
 * 注意:該類不應該在主應用程式上下文的@ComponentScan中
 */
@Configuration
@ExcludeComponent
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule() {
        // 負載均衡規則改為随機
        return new RandomRule();
    }

}      

  > 建立一個空類,并在其上添加@Configuration注解和@RibbonClient注解

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing.config;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;

/**
 * 使用RibbonClient,為特定name的Ribbon Client自定義配置
 * 使用@RibbonClient的configuration屬性,指定Ribbon的配置類
 */
@Configuration
@RibbonClient(name = "microservice-provider-user", configuration = RibbonConfiguration.class)
public class TestConfiguration {
}      

  > 啟動microservice-discovery-eureka

  > 啟動兩個以上的 microservice-provider-user 執行個體

  > 多次通路 http://localhost:8010/log-instance,可擷取類似如下的日志,表明負載均衡規則已改為随機

SpringCloud系列八:自定義Ribbon配置

3. 使用屬性自定義Ribbon配置

  從Spring Cloud Netflix1.2.0開始,Ribbon支援使用屬性自定義Ribbon用戶端。這種方式比使用Java代碼配置的方式更加友善。

  支援的屬性如下,配置的字首是<clientName>.ribbon.

  • NFLoadBalancerClassName:配置ILoadBalancer的實作類
  • NFLoadBalancerRuleClassName:配置IRule的實作類
  • NFLoadBalancerPingClassName:配置IPing的實作類
  • NIWSServerListClassName:配置ServerList的實作類
  • NIWSServerListFilterClassName:配置ServerListFilter的實作類

  > 複制項目 microservice-consumer-movie-ribbon,将ArtifactId修改為 microservice-consumer-movie-ribbon-customizing-properties

  > 在application.yml中添加一下内容

microservice-provider-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule      

  > 測試過程同上

4. 總結

  對于使用Java代碼自定義Ribbon配置的過程中,可指定該配置隻對某個Ribbon用戶端生效,也可對所有的Ribbon用戶端生效

  若隻對某個Ribbon用戶端生效,則RibbonConfiguration類不能包含在主應用程式上下文的@CompantScan中,是以本文添加了自定義注解,

    使用自定義注解和excludeFilters使RibbonConfiguration類不被@CompantScan掃描到

  若想對所有的Ribbon用戶端生效,隻須将RibbonConfiguration類包含在主應用程式上下文的@CompantScan中即可。

  下文将繼續講解脫離Eureka使用Ribbon,敬請期待~~~

5. 參考

  周立 --- 《Spring Cloud與Docker微服務架構與實戰》

轉載于:https://www.cnblogs.com/jinjiyese153/p/8656567.html