Feign with RibbonClient 和 Consul discovery without Spring Cloud
Feign with RibbonClient and Consul discovery without Spring Cloud
我试图将 Feign 设置为与 RibbonClient 一起工作,类似于 MyService api = Feign.builder().client(RibbonClient.create()).target(MyService.class, "https://myAppProd");
,其中 myAppProd 是我可以在 Consul 中看到的应用程序。现在,如果我为 Feign 客户端(@FeignClient("myAppProd")
、@RequestMapping
)使用 Spring 注释,一切正常 Spring 云模块将处理一切。
如果我想使用 Feign.builder()
和 @RequestLine
,我会得到错误:
com.netflix.client.ClientException: Load balancer does not have available server for client: myAppProd
.
我最初的想法是 Feign 是为与 Eureka 一起工作而构建的,只有 Spring Cloud 与 Consul 集成,但我不确定这一点。
那么,有没有办法让 Feign 在没有 Spring Cloud 的情况下与 Consul 一起工作?
提前致谢。
在我看来,这不是 feign work with consul,它是 feign -> ribbon -> consul。
RibbonClient 需要从其 LoadBalancer
中找到 myAppProd 的 serverList
。
没有 ServerList,错误:'does not have available server for client'.
这项工作已经由SpringCloudConsul 和SpringCloudRibbon 项目完成,当然你可以编写另一个适配器,它只是一些胶水代码。恕我直言,您可以将此 spring 依赖项导入到您的项目中,但 以非 spring 方式使用它 。演示代码:
只需编写一个新的 feign.ribbon.LBClientFactory
,生成带有 ConsulServerList(Spring 的 class) 的 LBClient。
public class ConsulLBFactory implements LBClientFactory {
private ConsulClient client;
private ConsulDiscoveryProperties properties;
public ConsulLBFactory(ConsulClient client, ConsulDiscoveryProperties consulDiscoveryProperties) {
this.client = client;
this.properties = consulDiscoveryProperties;
}
@Override
public LBClient create(String clientName) {
IClientConfig config =
ClientFactory.getNamedConfig(clientName, DisableAutoRetriesByDefaultClientConfig.class);
ConsulServerList consulServerList = new ConsulServerList(this.client, properties);
consulServerList.initWithNiwsConfig(config);
ZoneAwareLoadBalancer<ConsulServer> lb = new ZoneAwareLoadBalancer<>(config);
lb.setServersList(consulServerList.getInitialListOfServers());
lb.setServerListImpl(consulServerList);
return LBClient.create(lb, config);
}
}
然后在feign中使用它:
public class Demo {
public static void main(String[] args) {
ConsulLBFactory consulLBFactory = new ConsulLBFactory(
new ConsulClient(),
new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties()))
);
RibbonClient ribbonClient = RibbonClient.builder()
.lbClientFactory(consulLBFactory)
.build();
GitHub github = Feign.builder()
.client(ribbonClient)
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");
List<Contributor> contributors = github.contributors("OpenFeign", "feign");
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}
public static class Contributor {
String login;
int contributions;
}
}
你可以找到这个 demo code here,在 运行 这个演示之前添加 api.github.com
到你当地的领事。
我试图将 Feign 设置为与 RibbonClient 一起工作,类似于 MyService api = Feign.builder().client(RibbonClient.create()).target(MyService.class, "https://myAppProd");
,其中 myAppProd 是我可以在 Consul 中看到的应用程序。现在,如果我为 Feign 客户端(@FeignClient("myAppProd")
、@RequestMapping
)使用 Spring 注释,一切正常 Spring 云模块将处理一切。
如果我想使用 Feign.builder()
和 @RequestLine
,我会得到错误:
com.netflix.client.ClientException: Load balancer does not have available server for client: myAppProd
.
我最初的想法是 Feign 是为与 Eureka 一起工作而构建的,只有 Spring Cloud 与 Consul 集成,但我不确定这一点。
那么,有没有办法让 Feign 在没有 Spring Cloud 的情况下与 Consul 一起工作?
提前致谢。
在我看来,这不是 feign work with consul,它是 feign -> ribbon -> consul。
RibbonClient 需要从其 LoadBalancer
中找到 myAppProd 的 serverList
。
没有 ServerList,错误:'does not have available server for client'.
这项工作已经由SpringCloudConsul 和SpringCloudRibbon 项目完成,当然你可以编写另一个适配器,它只是一些胶水代码。恕我直言,您可以将此 spring 依赖项导入到您的项目中,但 以非 spring 方式使用它 。演示代码:
只需编写一个新的 feign.ribbon.LBClientFactory
,生成带有 ConsulServerList(Spring 的 class) 的 LBClient。
public class ConsulLBFactory implements LBClientFactory {
private ConsulClient client;
private ConsulDiscoveryProperties properties;
public ConsulLBFactory(ConsulClient client, ConsulDiscoveryProperties consulDiscoveryProperties) {
this.client = client;
this.properties = consulDiscoveryProperties;
}
@Override
public LBClient create(String clientName) {
IClientConfig config =
ClientFactory.getNamedConfig(clientName, DisableAutoRetriesByDefaultClientConfig.class);
ConsulServerList consulServerList = new ConsulServerList(this.client, properties);
consulServerList.initWithNiwsConfig(config);
ZoneAwareLoadBalancer<ConsulServer> lb = new ZoneAwareLoadBalancer<>(config);
lb.setServersList(consulServerList.getInitialListOfServers());
lb.setServerListImpl(consulServerList);
return LBClient.create(lb, config);
}
}
然后在feign中使用它:
public class Demo {
public static void main(String[] args) {
ConsulLBFactory consulLBFactory = new ConsulLBFactory(
new ConsulClient(),
new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties()))
);
RibbonClient ribbonClient = RibbonClient.builder()
.lbClientFactory(consulLBFactory)
.build();
GitHub github = Feign.builder()
.client(ribbonClient)
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");
List<Contributor> contributors = github.contributors("OpenFeign", "feign");
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}
public static class Contributor {
String login;
int contributions;
}
}
你可以找到这个 demo code here,在 运行 这个演示之前添加 api.github.com
到你当地的领事。