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,可擷取類似如下的日志,表明負載均衡規則已改為随機
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