2015-12-24 19 views
6

我有一個春天的雲應用程序,我自定義功能區客戶端作爲解釋here in section Customizing the Ribbon Client我的iRule是這樣的:通行證請求頭到功能區的iRule關鍵參數

public class HeadersRule extends AbstractLoadBalancerRule { 

public HeadersRule() { 
} 

public HeadersRule(ILoadBalancer lb) { 
    this(); 
    this.setLoadBalancer(lb); 
} 

public Server choose(ILoadBalancer lb, Object key) { 

    //I want the key to contain the headers from the request so I can decide choose the server by one of the headers 

    } 

我休息控制器:

@RequestMapping("/") 
public String hello(HttpServletRequest request, HttpServletResponse response) { 

    //here I want to pass the key parameter to ribbon 

    return result; 
} 

我想在我的IRule中通過其中一個標頭的值選擇下一個服務器。 我如何傳遞的標頭,以我的自定義的iRule關鍵參數?(通過RestTemplate或假裝或者如果你有一個使用色帶另一個選項...)類AbstractLoadBalancerAwareClient

編輯可能的方向

public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException { 
    RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, requestConfig); 
    LoadBalancerCommand<T> command = LoadBalancerCommand.<T>builder() 
      .withLoadBalancerContext(this) 
      .withRetryHandler(handler) 
      .withLoadBalancerURI(request.getUri()) 
      .build(); 

構建負載平衡器命令和省略:

.withServerLocator(request) 

會完成這項工作! 我可以從配置覆蓋此方法,在Spring RibbonClientConfiguration類我可以配置:

@Bean 
@Lazy 
@ConditionalOnMissingBean 
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer) { 
    RestClient client = new OverrideRestClient(config); 
    client.setLoadBalancer(loadBalancer); 
    Monitors.registerObject("Client_" + this.name, client); 
    return client; 
} 

的問題是,一些與名稱不工作:

@Value("${ribbon.client.name}") 
private String name = "client"; 

似乎有是一些配置應該用這個名字來完成,因爲我看到我的負載均衡服務器列表總是空的,出於某種原因,如果有人知道我應該如何配置這個屬性我相信它可以解決問題...

+0

功能區不知道當前的請求。它也運行在另一個線程中。 – spencergibb

+0

如果我可以將IRule選擇函數的關鍵參數傳遞給其餘模板,並將其傳遞給底層功能區,它將解決問題,我只是不知道如何...(可能會將自定義攔截器添加到其餘模板中,或者重寫另一個類,如負載平衡器......) –

+0

這可能是以下模式的一種:https://github.com/jmnarloch/ribbon-discovery-filter-spring-cloud-首發 – spencergibb

回答

3

我採取了一些修改以使其運行: 除了獲取ribbonRestClient bean之外,還需要提供ribbonServerList bean。但不要採用使用ConfigurationBasedServerList的RibbonClientConfiguration中定義的bean。這就是你得到一個空列表的原因。您可以定義服務器列表配置或者,如果你喜歡使用尤里卡採取豆從EurekaRibbonClientConfiguration代替:

@Bean 
@ConditionalOnMissingBean 
public ServerList<?> ribbonServerList(IClientConfig config) { 
    DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(
      config); 
    DomainExtractingServerList serverList = new DomainExtractingServerList(
      discoveryServerList, config, this.approximateZoneFromHostname); 
    return serverList; 
} 

,將動態填充您的服務器列表。 除此之外,請確保您用於覆蓋ribbonRestClientBean的配置文件未被自動掃描。 這是什麼引起的

@Value("${ribbon.client.name}") 
private String name = "client"; 

嘗試,並在應用程序加載填充。無論是把配置在不同的包,你的主應用程序類或掃描

最後排除,不要忘記添加@RibbonClient/@RibbonClients你的主類,以指向已重寫的配置

@RibbonClients(defaultConfiguration = {my.non.autoScanned.MyRibbonClientConfiguration.class}) 
@SpringBootApplication() 
public class MyApp { 
+0

偉大的它實際上工作! –