Estaba tratando de configurar Feign para trabajar con RibbonClient, algo así como MyService api = Feign.builder().client(RibbonClient.create()).target(MyService.class, "https://myAppProd");
, donde myAppProd es una aplicación que puedo ver en Consul. Ahora, si uso las anotaciones Spring para el cliente Feign ( @FeignClient("myAppProd")
, @RequestMapping
), todo funciona, ya que el módulo Spring Cloud se encargará de todo.
Si quiero usar Feign.builder()
y @RequestLine
, aparece el error: com.netflix.client.ClientException: Load balancer does not have available server for client: myAppProd
.
Mi primer pensamiento inicial fue que Feign fue creado para trabajar con Eureka y solo Spring Cloud hace la integración con Consul, pero no estoy seguro de esto.
Entonces, ¿hay alguna manera de hacer que Fingir funcione con Consul sin Spring Cloud?
Gracias por adelantado.
En mi opinión, no es fingir trabajar con el cónsul, es fingir -> listón -> cónsul.
RibbonClient necesita encontrar serverList de serverList
desde su LoadBalancer
. Sin ServerList, error: 'no tiene servidor disponible para el cliente'.
Este trabajo ha sido realizado por el proyecto SpringCloudConsul y SpringCloudRibbon, por supuesto, puede escribir otro adaptador, es solo un código de pegamento. En mi humilde opinión, puede importar esta dependencia de primavera en su proyecto, pero usarla de manera no primaveral . Código de demostración:
simplemente escriba un nuevo feign.ribbon.LBClientFactory
, que genere LBClient con ConsulServerList (clase de Spring).
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); } }
y luego usarlo en fingir:
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; } }
Puede encontrar este código de demostración aquí , agregue api.github.com
a su cónsul local antes de ejecutar esta demostración.