【发布时间】:2016-03-31 02:13:10
【问题描述】:
我有一个 Spring Cloud 应用程序,我正在按照 here in section Customizing the Ribbon Client 的说明自定义功能区客户端,我的 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 或 Feign,或者如果您有另一个使用 Ribbon 的选项...)
编辑可能的方向
在 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();
构建 LoadBalancer 命令并省略:
.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";
似乎应该用这个名称进行一些配置,因为我看到我的负载均衡器服务器列表由于某种原因总是空的,如果有人知道我应该如何配置这个属性我相信它可以解决问题.. .
【问题讨论】:
-
功能区不知道当前请求。它也在另一个线程中运行。
-
如果我可以将 IRule 选择函数的关键参数传递给其余模板,并将其传递给底层功能区,它将解决我只是不知道如何解决的问题......(也许将自定义拦截器添加到其余模板或覆盖另一个类,如负载均衡器...)
-
这可能是要模仿的东西:github.com/jmnarloch/…
-
@spencergibb 请看我的编辑,也许你能想到解决办法!无论如何感谢您的帮助!
标签: spring-mvc spring-cloud netflix