1. 程式人生 > 程式設計 >springcloud原始碼閱讀3-Ribbon負載均衡(上)

springcloud原始碼閱讀3-Ribbon負載均衡(上)

推薦閱讀:

SpringCloud原始碼閱讀0-SpringCloud必備知識

SpringCloud原始碼閱讀1-EurekaServer原始碼的祕密

SpringCloud原始碼閱讀2-Eureka客戶端的祕密

負載均衡提供客戶端的軟體負載均衡演演算法,理解一種負載均衡的內部結構,對理解其他種類負載均衡意義非凡。

1.核心元件

負載均衡元件包括:

  • rule: 負載均衡策略
  • ping:心跳檢測
  • ServerList: 服務列表
  • ServerListUpdater: 服務列表更新
  • ServerListFilter: 服務列表過濾

Spring Cloud Ribbon 是對 Netflix Ribbon的封裝。

Spring Cloud Ribbon 預設情況下為Ribbon核心元件提供如下的實現:

在這裡插入圖片描述

2.自定義Ribbon客戶端

對個別微服務,我們想替換其個別元件,怎麼辦?

2.1@RibbonClient

1.使用@RibbonClient 指定替換請求哪些服務哪些元件

@Configuration
@RibbonClient(name = "user",configuration = UserConfiguration.class)
public class UserRibbonConfiguration {
}
@Configuration
protected static class
UserConfiguration
{ @Bean public IPing ribbonPing() { return new MyPingUrl(); } } 複製程式碼

使用MyPingUrl 替換user對應的服務的Ribbon 客戶端 中的IPing 元件。

注意: 需要說明的是自定義的類必須加上@Configuration註解且不能包含在@componentscan註解掃描的包中,否則自定義的類將由所有加@ribbonclient註解的地方共享,若用@ComponentScan(或@SpringBootApplication),應該採取措施來避免它被包含到掃描的範圍中。

2.1屬性配置

2.使用屬性配置替換 從1.2.0版本開始,Spring Cloud Netflix支援自定義Ribbon客戶端配置 支援配置的屬性如下:

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

在這些屬性中定義的類優先於使用@RibbonClient()定義的bean和由Spring Cloud Netflix提供的預設值

例如: application.yml.

users:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
複製程式碼

替換users服務客戶端對應的 ServerList 與LoadBalancerRule 元件

3.自定義所有預設Ribbon

3.1@RibbonClients

當我們想替換所有客戶端的某個元件時,@RibbonClient就顯的力不從心了。

@RibbonClients註解用於覆蓋所有客戶端配置。

@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
public class RibbonClientDefaultConfigurationTestsConfig {

	public static class BazServiceList extends ConfigurationBasedServerList {

		public BazServiceList(IClientConfig config) {
			super.initWithNiwsConfig(config);
		}

	}

}

@Configuration
class DefaultRibbonConfig {

	@Bean
	public IRule ribbonRule() {
		return new BestAvailableRule();
	}

	@Bean
	public IPing ribbonPing() {
		return new PingUrl();
	}

	@Bean
	public ServerList<Server> ribbonServerList(IClientConfig config) {
		return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config);
	}

	@Bean
	public ServerListSubsetFilter serverListFilter() {
		ServerListSubsetFilter filter = new ServerListSubsetFilter();
		return filter;
	}

}
複製程式碼

4.與Eureka一起使用

當與Eureka一同使用時,部分元件被替換:

  • DiscoveryEnabledNIWSServerList 替換預設的(ribbonServerList)ConfigurationBasedServerList。DiscoveryEnabledNIWSServerList是由Eureka服務治理維護。
  • NIWSDiscoveryPing 替換預設的(IPing )DummyPing。 NIWSDiscoveryPing 也是由Eureka維護的。
  • 預設情況下安裝的ServerList是一個DomainExtractingServerList(其實這裡DomainExtractingServerList是對coveryEnabledNIWSServerList的一個代理)。其目的是使物理元資料可用於負載平衡器,而不使用AWS AMI元資料(這是Netflix依賴的)
  • Spring Cloud Ribbon預設使用eureka例項元資料中提供的“zone”資訊構建伺服器列表,通過設定eureka.instance.metadatamap.zone的值,可以實現跨區域的例項配置
  • 如果沒有配置區域,則可以使用伺服器主機名中的域名作為代理用於區域(前提是設定了標誌approximateZoneFromHostname)
  • ServerListFilter:服務例項清單過濾機制,預設採用org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter實現,該策略能夠優先過濾出與請求呼叫方處於同區域的服務例項

如果沒有其他的區域資料來源,則基於客戶端配置(與例項配置相反)進行猜測。我們將eureka.client.availabilityZones(從區域名稱對映到區域列表),並將例項自己的區域的第一個區域(即eureka.client.region,其預設為“us-east-1”為與本機Netflix的相容性)。

如何使用呢:

  1. RestTemplate新增@LoadBalanced註解,啟動RestTemplate客戶端負載均衡
	@LoadBalanced
	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
複製程式碼
  1. 直接使用Ribbon的api來實現負載均衡
public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;

    public void doStuff() {
        ServiceInstance instance = loadBalancer.choose("stores");
        URI storesUri = URI.create(String.format("http://%s:%s",instance.getHost(),instance.getPort()));
        // ... do something with the URI
    }
}
複製程式碼

5.脫離Eureka使用

當我們單獨使用Ribbon的時候,可以通過禁止Eureka來使用。

application.yml.

ribbon:
  eureka:
   enabled: false
複製程式碼

6.快取Ribbon配置

所謂快取Ribbon配置,其實就是飢餓載入(eager-load)模式。 Ribbon在第一次啟動時,因為需要從註冊中心獲取服務列表。一般建立比較慢,針對這種情況。 可以通過飢餓模式來,加速客戶端上下文的建立。

application.yml

ribbon:
  eager-load:
    enabled: true
    clients: client1,client2,client3
複製程式碼

參考: