8

I'm writing a Eureka Client Application using spring-cloud-starter-openfeign client. Here is my POM

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>service-registration-and-discovery-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-registration-and-discovery-client</name>
<description>Demo project for Spring Boot</description>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

As you can see, I'm using spring boot version 2.2.4.RELEASE spring-cloud.version Hoxton.SR1

This is my application class:

@SpringBootApplication
@EnableFeignClients
public class ServiceRegistrationAndDiscoveryClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceRegistrationAndDiscoveryClientApplication.class, args);
    }

}

Till herem My client application is getting registered on Eureka service successfully, i can see my applicaiton on Eureka page as well.

Now I've written an interface to call another service, which is registered on Eureka also,

@FeignClient("ANOTHER-SERVICE")
public interface SPProxy {

    @PostMapping("/anotherserviceplatform/api/resource/test")
    String testAPI(@RequestBody TestRequestBody request);
}

and I'm calling this method from one of my controller. but Feign is not resolving the service-name to It's URL. it is tryign to make http call to

http://ANOTHER-SERVICE/anotherservice/api/resource/test

instead of calling

http://192.168.1.1:8080/anotherservice/api/resource/test

and getting timeout exception (Which is obvious). below is the stacktrace

2020-01-31 13:03:56.281 ERROR 16693 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: connect timed out executing POST http://ANOTHER-SERVICE/anotherservice/api/resource/test] with root cause

java.net.SocketTimeoutException: connect timed out
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224) ~[na:na]
    at java.base/java.net.Socket.connect(Socket.java:591) ~[na:na]
    at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:341) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:362) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1248) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1187) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1081) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1015) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1362) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1337) ~[na:na]
    at feign.Client$Default.convertAndSend(Client.java:174) ~[feign-core-10.4.0.jar:na]
    at feign.Client$Default.execute(Client.java:77) ~[feign-core-10.4.0.jar:na]
    at org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:93) ~[spring-cloud-openfeign-core-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:56) ~[spring-cloud-openfeign-core-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:104) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:231) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144) ~[rxjava-1.3.8.jar:1.3.8]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.Subscriber.setProducer(Subscriber.java:209) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.Observable.subscribe(Observable.java:10423) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.Observable.subscribe(Observable.java:10390) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:443) ~[rxjava-1.3.8.jar:1.3.8]
    at rx.observables.BlockingObservable.single(BlockingObservable.java:340) ~[rxjava-1.3.8.jar:1.3.8]
    at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:112) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
    at org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:83) ~[spring-cloud-openfeign-core-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:110) ~[feign-core-10.4.0.jar:na]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:80) ~[feign-core-10.4.0.jar:na]
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.4.0.jar:na]
    at com.sun.proxy.$Proxy104.checkPincodeServiceability(Unknown Source) ~[na:na]
    at com.example.serviceregistrationanddiscoveryclient.ServiceInstanceRestController.serviceInstancesByApplicationName(ServiceRegistrationAndDiscoveryClientApplication.java:46) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.30.jar:9.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]

EDIT1: below is my application.properties

spring.application.name=test-client
eureka.client.serviceUrl.defaultZone=http://eurekahost:8761/eureka/
Abdul Mohsin
  • 1,253
  • 1
  • 13
  • 24
  • 1
    Pls show your `application.yml` (or `application.properties`) – amseager Jan 31 '20 at 13:32
  • @amseager application.properties added – Abdul Mohsin Feb 03 '20 at 05:28
  • Can you add more information about `ANOTHER-SERVICE` ? Also, is it available if you use raw URL instead of ribbon name in Feign client? – amseager Feb 03 '20 at 16:19
  • Yes It is available, even if i use DiscoverClient.getInstances("ANOTHER-SERVICE"), this is returning me the active instance with correct IP and PORT – Abdul Mohsin Feb 04 '20 at 11:39
  • I think you also need to add @DiscoveryClient at class ServiceRegistrationAndDiscoveryClientApplication to connect to erureka – Vipul Pandey Feb 10 '20 at 06:08
  • @Vipul didn't work :( – Abdul Mohsin Feb 10 '20 at 11:45
  • I saw in the applications.properties, that you have spring.application.name=test-client .That's the name of which one microservice? Have you tried to change the parameter of FeignClient to @FeignClient("test-client") .The FeignClient value has to match with the name of the app you are looking for to connect – ctorrez04 Feb 24 '20 at 16:03
  • @ctorrez04 . I have 2 apps, a client app that is trying to connect to another-service. this applicatino.properties file is for the client application. it's name is test-client. this app trying to connect to another-service – Abdul Mohsin Feb 26 '20 at 05:14
  • @AbdulMohsin did you get solution? – user530158 May 31 '20 at 20:40
  • any update on how did you solve it ? – Pri_stack Jun 01 '20 at 04:30

5 Answers5

4

There are one possible solutions:

So basically your Feign client becomes:

@FeignClient(name = "ANOTHER-SERVICE/anotherserviceplatform/api")
public interface SPProxy {
    @PostMapping("/resource/test")
    String testAPI(@RequestBody TestRequestBody request);
}

See the beautiful explanation on youtube:

OpenFeign Eureka Server Example

https://youtu.be/HSaSbWwE4TA

Hope this answer will work for you.

Tell Me How
  • 672
  • 12
  • 16
  • I had the same problem using the URL field in the FeignClient configuration, so when I removed the URL field everything was working successfully and Eureka names were resolved too. Thanks for the video – hermeslm Mar 18 '22 at 19:56
3

Recently I also faced the same issue. I was kind of able to figure out the root cause of this behavior when working with localhost.

Screenshot of issue reproduced at local

The whole reason for this to happen is that the eureka server is unable to resolve the http://currency-exchange-service/currency-exchange/from/USD/to/INR to http://localhost:9093/currency-exchange/from/USD/to/INR

if you check your Eureka server dashboard and hover the services registered you will see the hostname that eureka server is pointing as shown in below screenshot. If you hover link (under status column), the hostname we see is not correct which is causing this issue.

Screenshot of Eureka dashboard, the cause of the issue

Solution: Add the below property in your application.properties file of your Eureka client applications eureka.instance.hostname=localhost

in your case please put the appropriate host name.

and that should be it. After making the change restart you client applications. Go to you Eureka Dashboard again hover the link for you registered applications this should look something like below:

Screen shot of Eureka server dashboard after making the appropriate changes .

After making the changes please try and access your Http request using the feign client. It worked for me. Screenshot of the final result with API result

1

you can use restTemplate.exchange from spring automatically

or

private String getAnotherServiceBaseAddress() {

        try {

            InstanceInfo info = getEurekaClient().getNextServerFromEureka("another-service", false);
            if (info == null || info.getHomePageUrl() == null)
                return "(default)http://192.168.1.1:8080/anotherservice";
            else
                return info.getHomePageUrl()+"/anotherservice;

        } catch (NullPointerException e) {
             return "(default)http://192.168.1.1:8080/anotherservice";
        }
    }

public static EurekaClient getEurekaClient() {
    return applicationContext.getBean(EurekaClient.class);
}


finally:

HttpGet http = new HttpGet(getAnotherServiceBaseAddress() + "/api/resource/test");
Negar Zamiri
  • 641
  • 2
  • 11
  • 16
  • I know i can go with this way. but due to some reason I have to use FeignClient. so that it will take care all the stuff internally and i do not have to make http calls manually. – Abdul Mohsin Feb 10 '20 at 07:48
1

There is one more reason for that:

1 - Check the application properties it should be like that :

spring.application.name=reception-service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka
eureka.client.enabled=true
spring.cloud.config.enabled=false
eureka.instance.hostname=localhost 

2 - Make sure the service name is in capital letters, not small letters : like that :

@FeignClient(name = "INSURANCE", path = "/apis/v1/inc")

Not like

@FeignClient(name = "Insurance", path = "/apis/v1/inc")

3 - Add important annotation :

@SpringBootApplication
@EnableFeignClients
Abd Abughazaleh
  • 4,615
  • 3
  • 44
  • 53
0

Adding eureka.client.enabled=true to application.properties file fixed issue for me

damndemon
  • 331
  • 3
  • 11