Spring Cloud Document翻譯(八)--客戶端負載均衡器:Ribbon

16.客戶端負載均衡器:Ribbon

Ribbon是一個客戶端負載均衡器,可以讓您對HTTP和TCP客戶端的行爲進行大量控制。Feign已使用Ribbon,因此,如果您使用@FeignClient,此部分也適用。

Ribbon中的一個核心概念是指定客戶端的概念。每個負載均衡器都是一組組件的一部分,這些組件一起工作以按需聯繫遠程服務器,並且該集合具有您作爲應用程序開發人員提供的名稱(例如,通過使用@FeignClient註釋)。根據需要,Spring Cloud 通過使用RibbonClientConfiguration爲每個命名客戶端 創建一個新的ApplicationContext集合。這包含(除其他外)a ILoadBalancer,a RestClient和a ServerListFilter

16.1如何包含Ribbon

要在項目中包含Ribbon,請使用組ID爲ID org.springframework.cloud且工件ID爲 spring-cloud-starter-netflix-ribbon的starter。有關使用當前Spring Cloud Release Train設置構建系統的詳細信息,請參閱Spring Cloud Project頁面

16.2自定義Ribbon客戶端

您可以使用<client>.ribbon.*中的外部屬性配置Ribbon客戶端的某些位,這類似於本機使用Netflix API,但您可以使用Spring Boot配置文件。可以將本機選項作爲靜態字段CommonClientConfigKey(ribbon-core的一部分)進行檢查。

Spring Cloud還允許您通過使用聲明@RibbonClient的其他配置(在RibbonClientConfiguration的上方)來完全控制客戶端,如以下示例所示:

@Configuration
@RibbonClient(name = "custom", configuration = CustomConfiguration.class)
public class TestConfiguration {
}

在這種情況下,客戶端由已經存在在RibbonClientConfiguration中的組件CustomConfiguration中的組件組成(後者通常覆蓋前者)。

[警告]

CustomConfiguration類必須是@Configuration的類,但要小心,它不被@ComponentScan掃入主應用程序上下文。否則,它由所有人共享@RibbonClients。如果使用@ComponentScan(或@SpringBootApplication),則需要採取措施以避免包含它(例如,您可以將其放在單獨的非重疊包中或指定要在其中顯式掃描的包@ComponentScan)。

下表顯示了Spring Cloud Netflix默認爲Ribbon提供的bean:

Bean類型 Bean名 類名稱

IClientConfig

ribbonClientConfig

DefaultClientConfigImpl

IRule

ribbonRule

ZoneAvoidanceRule

IPing

ribbonPing

DummyPing

ServerList<Server>

ribbonServerList

ConfigurationBasedServerList

ServerListFilter<Server>

ribbonServerListFilter

ZonePreferenceServerListFilter

ILoadBalancer

ribbonLoadBalancer

ZoneAwareLoadBalancer

ServerListUpdater

ribbonServerListUpdater

PollingServerListUpdater

創建其中一種類型的bean並將其放在@RibbonClient配置中(FooConfiguration如上所述)可以覆蓋所描述的每一個bean,如下例所示:

@Configuration
protected static class FooConfiguration {

	@Bean
	public ZonePreferenceServerListFilter serverListFilter() {
		ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
		filter.setZone("myTestZone");
		return filter;
	}

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

}

前面示例中的include語句替換NoOpPingPingUrl並提供自定義serverListFilter

16.3自定義所有Ribbon客戶端的默認值

可以使用@RibbonClients註釋並註冊默認配置爲所有Ribbon客戶端提供默認配置,如以下示例所示:

@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;
	}

}

16.4通過設置屬性自定義Ribbon客戶端

從版本1.2.0開始,Spring Cloud Netflix現在支持通過將屬性設置爲與Ribbon文檔兼容來自定義Ribbon客戶端。

這使您可以在不同環境中的啓動時更改行爲。

以下列表顯示了支持的屬性>:

  • <clientName>.ribbon.NFLoadBalancerClassName:應該實現 ILoadBalancer
  • <clientName>.ribbon.NFLoadBalancerRuleClassName:應該實現 IRule
  • <clientName>.ribbon.NFLoadBalancerPingClassName:應該實現 IPing
  • <clientName>.ribbon.NIWSServerListClassName:應該實現 ServerList
  • <clientName>.ribbon.NIWSServerListFilterClassName:應該實現 ServerListFilter
[注意]

這些屬性中定義的類優先於使用@RibbonClient(configuration=MyRibbonConfig.class)Spring 定義的bean 和Spring Cloud Netflix提供的缺省值。

要設置IRule名爲users的服務名稱,您可以設置以下屬性:

application.yml。 

users:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

 

有關Ribbon提供的實現,請參閱Ribbon文檔

16.5在Eureka上使用Ribbon

當Eureka與Ribbon一起使用時(也就是說,兩者都在類路徑上)時,ribbonServerList會被覆蓋爲一個DiscoveryEnabledNIWSServerList的擴展,它會從Eureka獲得服務器列表。它還替換了IPing接口用NIWSDiscoveryPing,該接口委託Eureka確定服務器是否已啓動。該ServerList默認被安裝的是DomainExtractingServerList。其目的是在不使用AWS AMI元數據的情況下使負載均衡器可以使用元數據(這是Netflix所依賴的)。默認情況下,服務器列表由“ 區域 ”信息構成,如實例元數據中所提供的(因此,在遠程客戶端上設置eureka.instance.metadataMap.zone)。如果缺少那個,如果approximateZoneFromHostname設置了標誌,則可以使用服務器主機名中的域名作爲區域的代理。區域信息可用後,可以在ServerListFilter中使用。默認情況下,它用於在與客戶端相同的區域中查找服務器,因爲默認值爲a ZonePreferenceServerListFilter。默認情況下,客戶端的區域以與遠程實例相同的方式確定(即,通過eureka.instance.metadataMap.zone)。

[注意]

設置客戶區的正統“ archaius ”方法是通過名爲“@zone”的配置屬性。如果可用,Spring Cloud優先於所有其他設置使用它(請注意,必須在YAML配置中引用密鑰)。

[注意]

如果沒有其他區域數據源,則根據客戶端配置(與實例配置相反)進行猜測。我們採用eureka.client.availabilityZones從區域名稱到區域列表的映射,並拉出實例自己區域的第一個區域(即eureka.client.region,默認爲“us-east-1”,以與本機Netflix兼容) 。

16.6示例:如何在沒有Eureka的情況下使用Ribbon

Eureka是一種抽象遠程服務器發現的便捷方式,因此您無需在客戶端中對其URL進行硬編碼。但是,如果您不想使用Eureka,Ribbon和Feign也可以使用。假設你已經@RibbonClient爲“商店” 聲明瞭一個,並且Eureka沒有被使用(甚至沒有在類路徑上)。Ribbon客戶端默認爲已配置的服務器列表。您可以按如下方式提供配置:

application.yml。 

stores:
  ribbon:
    listOfServers: example.com,google.com

 

16.7示例:禁用Ribbon中的Eureka使用

設置該ribbon.eureka.enabled屬性以false顯式禁用在Ribbon中使用Eureka,如以下示例所示:

application.yml。 

ribbon:
  eureka:
   enabled: false

 

16.8直接使用Ribbon API

您也可以LoadBalancerClient直接使用,如下例所示:

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
    }
}

16.9Ribbon配置的緩存

名爲client的每個Ribbon都有一個Spring Cloud維護的相應子應用程序上下文。在對指定客戶端的第一個請求上延遲加載此應用程序上下文。通過指定Ribbon客戶端的名稱,可以將此延遲加載行爲更改爲在啓動時急切地加載這些子應用程序上下文,如以下示例所示:

application.yml。 

ribbon:
  eager-load:
    enabled: true
    clients: client1, client2, client3

 

16.10如何配置Hystrix線程池

如果更改zuul.ribbonIsolationStrategyTHREAD,則Hystrix的線程隔離策略將用於所有路由。在這種情況下,將HystrixThreadPoolKey其設置RibbonCommand爲默認值。這意味着所有路由的HystrixCommands都在同一個Hystrix線程池中執行。可以使用以下配置更改此行爲:

application.yml。 

zuul:
  threadPool:
    useSeparateThreadPools: true

 

前面的示例導致HystrixCommands在Hystrix線程池中爲每個路由執行。

在這種情況下,默認值HystrixThreadPoolKey與每個路由的服務ID相同。要添加前綴HystrixThreadPoolKey,請設置zuul.threadPool.threadPoolKeyPrefix爲要添加的值,如以下示例所示:

application.yml。 

zuul:
  threadPool:
    useSeparateThreadPools: true
    threadPoolKeyPrefix: zuulgw

 

16.11如何爲Ribbon提供密鑰 IRule

如果您需要提供自己的IRule實現來處理特殊的路由要求,如“ canary ”測試,請將一些信息傳遞給choose方法IRule

com.netflix.loadbalancer.IRule.java。 

public interface IRule{
    public Server choose(Object key);
         :

 

您可以提供IRule實現用於選擇目標服務器的一些信息,如以下示例所示:

RequestContext.getCurrentContext()
              .set(FilterConstants.LOAD_BALANCER_KEY, "canary-test");

如果將任何對象放入RequestContext帶有鍵的對象中FilterConstants.LOAD_BALANCER_KEY,則將其傳遞給實現的choose方法IRule。必須在執行前RibbonRoutingFilter執行前面示例中顯示的代碼。Zuul的預過濾器是最好的選擇。您可以通過RequestContext預過濾器訪問HTTP標頭和查詢參數,因此可以用它來確定LOAD_BALANCER_KEY傳遞給Ribbon的內容。如果你不把任何值與LOAD_BALANCER_KEYRequestContext,null被作爲一個參數傳遞choose方法。

17.外部配置:Archaius

Archaius是Netflix客戶端配置庫。它是所有Netflix OSS組件用於配置的庫。Archaius是Apache Commons Configuration項目的擴展。它允許通過輪詢源更改或允許源推送更改到客戶端來更新配置。Archaius使用Dynamic <Type> Property類作爲屬性的句柄,如以下示例所示:

Archaius示例。 

class ArchaiusTest {
    DynamicStringProperty myprop = DynamicPropertyFactory
            .getInstance()
            .getStringProperty("my.prop");

    void doSomething() {
        OtherClass.someMethod(myprop.get());
    }
}

 

Archaius有自己的一組配置文件和加載優先級。Spring應用程序通常不應直接使用Archaius,但仍然需要本機配置Netflix工具。Spring Cloud有一個Spring Environment Bridge,因此Archaius可以從Spring環境中讀取屬性。此橋接器允許Spring Boot項目使用常規配置工具鏈,同時讓他們按照文檔(大多數情況下)配置Netflix工具。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章