spring-cloud / spring-cloud-netflix

Integration with Netflix OSS components
http://cloud.spring.io/spring-cloud-netflix/
Apache License 2.0
4.88k stars 2.44k forks source link

Feign + Ribbon Not Finding Service #83

Closed ryanjbaxter closed 9 years ago

ryanjbaxter commented 10 years ago

I am trying to use Feign + Ribbon to call an endpoint of my service. My understanding is that Ribbon will use Eureka to look up the URL to the service. Following the documentation I created a class which extends FeignConfigurer

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
public class App extends FeignConfigurer {

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

  @Bean
  public QuestionsClient questionsClient() {
    return loadBalance(QuestionsClient.class, "http://questions");
  }

}

It was also my understanding that the second argument to loadBalance is the service name registered in Eureka with http:// prepended, correct?

When I run this I get a NPE. The log message is a little concerning to me since the current list of servers is empty, I am guessing that is referring to Eureka servers? I thought maybe I had to explicitely set eureka.client.serviceUrl.defaultZone (I usually don't since my Eureka server is running on localhost at the default port) but that didn't make a difference either.

2014-12-03 12:25:42.506  WARN 4936 --- [nio-8383-exec-1] com.netflix.loadbalancer.RoundRobinRule  : No up servers available from load balancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=questions,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@4018ad37
2014-12-03 12:25:42.516 ERROR 4936 --- [nio-8383-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at feign.ribbon.LoadBalancingTarget.apply(LoadBalancingTarget.java:93)
    at feign.MethodHandler$SynchronousMethodHandler.targetRequest(MethodHandler.java:174)
    at feign.MethodHandler$SynchronousMethodHandler.executeAndDecode(MethodHandler.java:117)
    at feign.MethodHandler$SynchronousMethodHandler.invoke(MethodHandler.java:105)
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:87)
    at com.sun.proxy.$Proxy57.markAnswered(Unknown Source)
    at com.sessionqa.reply.ReplyController.reply(ReplyController.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:98)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:288)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:744)
spencergibb commented 10 years ago

@ryanjbaxter what does eureka say is registered?

ryanjbaxter commented 10 years ago

When I hit eureka/apps I see the service with the name questions there.

<applications>
  <versions__delta>1</versions__delta>
  <apps__hashcode>UP_5_</apps__hashcode>
  <application>
    <name>EUREKA</name>
    <instance>
      <hostName>ryans-macbook-pro.usma.ibm.com</hostName>
      <app>EUREKA</app>
      <ipAddr>9.32.121.34</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8761</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1417631512749</registrationTimestamp>
        <lastRenewalTimestamp>1417631512749</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1417631502448</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap"/>
      <homePageUrl>http://ryans-macbook-pro.usma.ibm.com:8761/</homePageUrl>
      <statusPageUrl>http://ryans-macbook-pro.usma.ibm.com:8761/info</statusPageUrl>
      <healthCheckUrl>http://ryans-macbook-pro.usma.ibm.com:8761/health</healthCheckUrl>
      <vipAddress>eureka</vipAddress>
      <isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1417631512749</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1417631472434</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
  <application>
    <name>REPLY</name>
    <instance>
      <hostName>ryans-macbook-pro.usma.ibm.com</hostName>
      <app>REPLY</app>
      <ipAddr>9.32.121.34</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8383</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1417631502176</registrationTimestamp>
        <lastRenewalTimestamp>1417631502176</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1417631502091</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap"/>
      <homePageUrl>http://ryans-macbook-pro.usma.ibm.com:8383/</homePageUrl>
      <statusPageUrl>http://ryans-macbook-pro.usma.ibm.com:8383/info</statusPageUrl>
      <healthCheckUrl>http://ryans-macbook-pro.usma.ibm.com:8383/health</healthCheckUrl>
      <vipAddress>reply</vipAddress>
      <isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1417631502176</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1417628361286</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
  <application>
    <name>SESSIONS</name>
    <instance>
      <hostName>ryans-macbook-pro.usma.ibm.com</hostName>
      <app>SESSIONS</app>
      <ipAddr>9.32.121.34</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8080</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1417631499160</registrationTimestamp>
        <lastRenewalTimestamp>1417631499160</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1417631498692</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap"/>
      <homePageUrl>http://ryans-macbook-pro.usma.ibm.com:8080/</homePageUrl>
      <statusPageUrl>http://ryans-macbook-pro.usma.ibm.com:8080/info</statusPageUrl>
      <healthCheckUrl>http://ryans-macbook-pro.usma.ibm.com:8080/health</healthCheckUrl>
      <vipAddress>sessions</vipAddress>
      <isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1417631499160</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1417621816531</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
  <application>
    <name>WEB</name>
    <instance>
      <hostName>ryans-macbook-pro.usma.ibm.com</hostName>
      <app>WEB</app>
      <ipAddr>9.32.121.34</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8282</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1417631480090</registrationTimestamp>
        <lastRenewalTimestamp>1417631480090</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1417631479833</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap"/>
      <homePageUrl>http://ryans-macbook-pro.usma.ibm.com:8282/</homePageUrl>
      <statusPageUrl>http://ryans-macbook-pro.usma.ibm.com:8282/info</statusPageUrl>
      <healthCheckUrl>http://ryans-macbook-pro.usma.ibm.com:8282/health</healthCheckUrl>
      <vipAddress>web</vipAddress>
      <isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1417631480090</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1417622457579</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
  <application>
    <name>QUESTIONS</name>
    <instance>
      <hostName>ryans-macbook-pro.usma.ibm.com</hostName>
      <app>QUESTIONS</app>
      <ipAddr>9.32.121.34</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">8181</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
        <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
        <renewalIntervalInSecs>30</renewalIntervalInSecs>
        <durationInSecs>90</durationInSecs>
        <registrationTimestamp>1417631500665</registrationTimestamp>
        <lastRenewalTimestamp>1417631500665</lastRenewalTimestamp>
        <evictionTimestamp>0</evictionTimestamp>
        <serviceUpTimestamp>1417631500540</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap"/>
      <homePageUrl>http://ryans-macbook-pro.usma.ibm.com:8181/</homePageUrl>
      <statusPageUrl>http://ryans-macbook-pro.usma.ibm.com:8181/info</statusPageUrl>
      <healthCheckUrl>http://ryans-macbook-pro.usma.ibm.com:8181/health</healthCheckUrl>
      <vipAddress>questions</vipAddress>
      <isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1417631500665</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1417626979512</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
    </instance>
  </application>
</applications>
spencergibb commented 10 years ago

so then is the app that is calling questions communicating with eureka? You should be able to see eureka information in /health.

ryanjbaxter commented 10 years ago

I believe so, it is the reply service that is also in the above xml the came from Eureka.

When I hit /health on any service I just see {"status":"DOWN"}

spencergibb commented 10 years ago

my guess is that your service isn't talking to eureka. What version of spring-cloud are you using?

spencergibb commented 10 years ago

Spring-boot snapshot (and spring-cloud snapshot) allows you to set health.sensitive=false so that you can see the health details.

ryanjbaxter commented 10 years ago

I am using the M3 release of spring cloud

ryanjbaxter commented 10 years ago

If the service isn't talking to eureka, how would eureka know about about the service in the dashboard?

spencergibb commented 10 years ago

I didn't know what service was trying to talk to questions. Something is wrong if {"status":"DOWN"}. Do you have some code to share? It is hard to guess as to why eureka client isn't getting a list of instances from eureka server.

ryanjbaxter commented 10 years ago

I will try to put together something simple to show the problem and share it with you.

ryanjbaxter commented 10 years ago

@spencergibb take a look at the project here https://github.com/ryanjbaxter/spring-cloud-demo

Take a look at https://github.com/ryanjbaxter/spring-cloud-demo/tree/master/spring-cloud-feign-rest. The project is kind of pointless but demonstrates the problem.

spencergibb commented 10 years ago

M3 has an issue (now resolved) where the eureka starter doesn't include ribbon-eureka. If you include spring-cloud-starter-hystrix it will fix this. I just helped @joshlong with this very issue.

ryanjbaxter commented 10 years ago

@spencergibb thanks I will give that a shot tomorrow and let you know!

ryanjbaxter commented 9 years ago

That worked thanks!