本文目錄
- Client Side Load Balancer:Ribbon
- How to Include Ribbon
- Customizing the Ribbon Client
- Customizing the Default for All Ribbon Clients
- Customizing the Ribbon Client by Setting Properties
- Using Ribbon with Eureka
- Example: How to Use Ribbon Without Eureka
- Example: Disable Eureka Use in Ribbon
- Using the Ribbon API Directly
- Caching of Ribbon Configuration
- How to Configure Hystrix Thread Pools
- How to Provide a Key to Ribbon's IRule
Client Side Load Balancer:Ribbon
Ribbon是一個客戶端的負載均衡器,可以用來控制HTTP和TCP客戶端的行爲。
Ribbon核心的概念是命名的客戶端。每個負載均衡器作爲組件團體的一部分,這些組件會按需共同協作去聯絡一個遠程服務端。此外,這個團體通過在@FeignClient註解指定name屬性的方式設定一個名字。Spring Cloud爲每個命名的客戶端通過使用RibbonClientConfiguration的方式創建了一個新的團體,作爲一個ApplicationContext。這包含了一個ILoadBalancer,RestTemplate,ServerListFilter。
How to Include Ribbon
Customizing the Ribbon Client
可以在配置文件中,指定<client>.ribbon.*
,對一個Ribbon客戶端進行配置。在CommonClientConfigKey
這個類中根據需要,尋找對應的屬性進行設置。
可以指定一個配置類,作爲該Ribbon客戶端的配置。
在@RibbonClient註解中指定的自定義的配置類,必須是一個@Configuration類。不要被主應用程序上下文的@ComponentScan註解掃描到,否則會被所有的@RibbonClients所共享。可以將它放到一個獨立的、與@ComponentScan掃描的包不重疊的包中。
Customizing the Default for All Ribbon Clients
爲所有的Ribbon客戶端,提供一個默認的配置,註冊它。
Customizing the Ribbon Client by Setting Properties
從版本1.2.0開始,Spring Cloud Netflix支持自定義Ribbon客戶端,通過設置一些屬性。
可以對服務名叫做“users”的,進行設置。
users:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
Using Ribbon with Eureka
當Eureka和Ribbon組合使用(也就是,兩者都在類路徑中),ribbonServerList由DiscoveryEnabledNIWSServerList進行重寫,其添加了來自Eureka的服務器列表。替換IPing爲NIWSDiscoveryPing,委派Eureka判斷服務器是否上線。ServerList,默認由一個DomainExtractingServerList設置。這個目的是使元數據對於負載均衡器可用,而沒有使用AWS AMI元數據(這個是Netflix所依賴的)。默認,服務器列表使用“zone”信息進行構造(對於遠程客戶端,設置eureka.instance.metadataMap.zone
)。如果這個缺失了,並且有設置approximateZoneFromHostname
標識,可以使用服務器主機名的域名作爲時區的一個代理。一旦時區信息可用,可以在ServerListFilter中被使用。默認,這個可以被用來定位和客戶端相同的時區的服務器,因爲默認是一個ZonePreferenceServerListFilter
。默認,客戶端的時區和遠程實例使用相同的方式設置,即使用eureka.instance.metadataMap.zone
。
Example: How to Use Ribbon Without Eureka
Eureka是一個遠程服務發現的便捷的方式,不需要對客戶端URL硬編碼。如果不想使用Eureka,Ribbon和Feign也能正常工作。假設有一個聲明@RibbonClient的"stores",沒有使用Eureka(甚至都沒有在類路徑中)。Ribbon客戶端默認使用一個配置過的服務器列表。如下:
stores:
ribbon:
listOfServers: example.com,google.com
Example: Disable Eureka Use in Ribbon
設置在Ribbon中關閉Eureka的使用,如下:
ribbon:
eureka:
enabled: false
Using the Ribbon API Directly
可以直接使用LoadBalancerClient
,如下:
public class MyClass {
@Autowired
private LoadBalancerClient loadBalancer;
public void doStuff() {
ServiceInstance instance = loadBalancer.choose("stores");
URI storeUri = URI.create(String.format("https://%s:%s", instance.getHost(), instance.getPort()));
// ... doSomething with the URI
}
}
Caching of Ribbon Configuration
每一個Ribbon命名的客戶端,有一個對應的由Spring Cloud維護的子上下文。這個上下文是延遲加載的,直到有請求到命名的客戶端時才加載。這個延遲加載的行爲可以設置爲啓動時,就進行加載。如下:
ribbon:
eager-load:
enabled: true
clients: client1, client2, client3
How to Configure Hystrix Thread Pools
如果對zuul.ribbonIsolationStrategy
設置爲THREAD
,線程隔離策略對於Hystrix來說,會用於所有的routes。這種情況下,HystrixThreadPoolKey默認設置爲RibbonCommand
。也就意味着,對於所有的routes的HystrixCommands會在同一個Hystrix線程池中執行。這個可以通過如下的方式改變:
zuul:
threadPool:
useSeparateThreadPools: true
這種設置,會導致HystrixCommands會在每一個route的Hystrix線程池中執行。這種情況下,默認的HystrixThreadPoolKey和每個route的service ID相同。可以通過如下方式添加一個自定義的前綴:
zuul:
threadPool:
useSeparateThreadPools: true
threadPoolKeyPrefix: zuulgw
How to Provide a Key to Ribbon’s IRule
如果要求IRule實現類,處理一個特殊的路由要求,比如一個“金絲雀測試”,那麼在IRule的chosse方法中傳遞一些信息。
public interface IRule {
public Server choose(Object key);
}
此外,可以通過以下方式,傳遞一些信息:
RequestContext.getCurrentContext().set(FilterConstants.LOAD_BALANCER_KEY, "canary-test");
上面的代碼要求在RibbonRoutingFilter
執行之前被執行。Zuul
的前置過濾器是最佳的方式去做這件事。你可以在其前置過濾器中使用 RequestContext
,訪問HTTP頭和查詢參數。所以可以用來設置LOAD_BALANCER_KEY
。如果在RequestContext
中沒有設置LOAD_BALANCER_KEY
任何值,那麼對於choose方法會傳遞null
作爲方法參數。