6

Ich arbeite an Spring Boot Eureka Client-Anwendung mit Ribbon Load Balancer.Ribbon mit Spring Cloud und Eureka: java.lang.IllegalStateException: Keine Instanzen für Samarths-MacBook-Pro.local verfügbar

Ich habe zwei Instanzen des Servers bei Eureka mit dem Namen "TEST" registriert. Auf der Client-Seite habe ich den folgenden Code, um den Server von Eureka zu holen.

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
@EnableEurekaClient 
@RestController 
public class EurekaConsumerApplication { 

@Autowired 
DiscoveryClient discoveryClient; 

@Autowired 
RestTemplate restTemplate; 

@RequestMapping(value = "/",method = RequestMethod.GET) 
String consumer(){ 
InstanceInfo instance = discoveryClient.getNextServerFromEureka("TEST",  false); 

URI uri = UriComponentsBuilder.fromUriString(instance.getHomePageUrl() + "baseDir") 
     .build() 
     .toUri(); 
String baseDir = restTemplate.getForObject(uri, String.class); 

return baseDir; 

} 

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

}

application.yml

spring: 
    application: 
    name: consumer 
info: 
    component: Consumer to fetch configuration 
server: 
    port: 8090 
eureka: 
    instance: 
    leaseRenewalIntervalInSeconds: 3 
    metadataMap: 
    instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}} 
client: 
# Default values comes from org.springframework.cloud.netflix.eurek.EurekaClientConfigBean 
    region: default 
    registryFetchIntervalSeconds: 5 
    instanceInfoReplicationIntervalSeconds: 5 
    initialInstanceInfoReplicationIntervalSeconds: 5 
    serviceUrl: 
    defaultZone: http://localhost:8761/eureka/ 
    availabilityZones: 
    default: ${APPLICATION_DOMAIN:${DOMAIN:defaultZone}} 

Allerdings, wenn ich den ruhigen Endpunkt treffen: curl http://localhost:8090/, gibt es mir die folgende Fehlermeldung: "Ausnahme": "java.lang .IllegalStateException "," message ": org.springframework.web.util.NestedServletException: Anforderungsverarbeitung fehlgeschlagen; verschachtelte Ausnahme ist java.lang.IllegalStateException: Keine Instanzen für Samarths-MacBook-Pro.local verfügbar", "path": "/"}

Stacktrace:

2015-07-22 14:37:35.005 INFO 13841 --- [tp1334391583-19] c.netflix.loadbalancer.BaseLoadBalancer : Client:Samarths-MacBook-Pro.local instantiated a LoadBalancer:DynamicServerListLoadBalancer:{NFLoadBalancer:name=Samarths-MacBook-Pro.local,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null 
2015-07-22 14:37:35.009 INFO 13841 --- [tp1334391583-19] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client Samarths-MacBook-Pro.local initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=Samarths-MacBook-Pro.local,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:org.springf[email protected]681eda37 
2015-07-22 14:37:35.029 WARN 13841 --- [tp1334391583-19] o.eclipse.jetty.servlet.ServletHandler : 

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) 
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) 
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:295) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:102) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.eclipse.jetty..ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:68) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) 
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) 
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) 
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) 
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) 
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) 
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) 
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) 
at org.eclipse.jetty.server.Server.handle(Server.java:499) 
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) 
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) 
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) 
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) 
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local 
at org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory.createRequest(RibbonClientHttpRequestFactory.java:64) 
at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:76) 
at org.springframework.web.client.Rlate.doExecute(RestTemplate.java:565) 
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545) 
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:253) 
at com.securityscorecard.eureka.consumer.EurekaConsumerApplication.consumer(EurekaConsumerApplication.java:53) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
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:776) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
... 38 common frames omitted 

wie meine Serverliste Looks ist leer.

Antwort

7

Die RestTemplate autowired ist bereits mit Ribbon verbunden. Sie tun also eine Suche von Hand und dann versucht RestTemplate nach dem Hostnamen zu suchen, der in Multifunktionsleiste übergeben wird. Sie haben zwei Möglichkeiten: 1) Verwenden Sie nicht die Netflix DiscoveryClient und übergeben Sie die Service-ID als logischer Hostname zu Multifunktionsleiste (http://TEST/myservice), 2) Verwenden Sie nicht die Autowired RestTemplate, erstellen Sie eine neue für Ihre Klasse. Meine Wahl wäre # 1.

+0

Danke für die Anregung. Ich habe eine Variante Ihrer ersten Wahl verwendet, um mein Problem zu beheben. – Samarth

+0

Ein Link zu der Dokumentation: http: //projects.spring.io/spring-cloud/spring-cloud.html#_spring_resttemplate_as_a_load_balancer_client –

4

Ich habe das funktioniert. Die einzige Änderung, die ich vornehmen musste, war die Art und Weise, wie ich RestTemplate api verwendete.

Fehlercode:

@Autowired 
RestTemplate restTemplate; 

@RequestMapping(value = "/",method = RequestMethod.GET) 
String consumer(){ 
    String baseDir = restTemplate.getForObject("TEST", String.class); 

    return baseDir; 
} 

Arbeits Code:

@Autowired 
RestTemplate restTemplate; 

@RequestMapping(value = "/",method = RequestMethod.GET) 
String consumer(){ 
    String baseDir = restTemplate.getForObject("http://TEST", String.class); 

    return baseDir; 
} 

Lösung:

Der erste Parameter für restTemplate.getForObject sollte das Format einer URL haben. Und der Domänenname sollte der Name des Dienstes sein, den Sie ermitteln möchten.

Beispiel: http://TEST. Hier ist TEST der Name meines Servers registriert in Eureka Registry

+1

Yup, das ist, was ich gesagt habe, dass Sie tun mussten. – spencergibb

1

Die Frage ist bereits beantwortet, aber ich fand eine Abhilfe, die sauber scheint und unser Problem behoben.

zunächst eine neue @Component Klasse deklarieren und darin eine Methode erstellen, die RestTemplate zurückgibt:

@Component 
public class RestTemplateComponentFix{ 

@Autowired 
SomeConfigurationYouNeed someConfiguration; 

@LoadBalanced 
public RestTemplate getRestTemplate() { 
     // TODO set up your restTemplate 
     rt.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); 
     return rt; 
    } 

} 

Danach nur Autowire die restTemplateComponentFix in Ihrer Klasse und wenn, wenn Sie den Rest Vorlage rufen Sie die restTemplate benötigen() Methode.Etwas wie folgt aus:

@Service 
public class someClass{ 

    @Autowired 
    RestTemplateComponentFix restTemplateComponentFix; 

    public void methodUsingRestTemplate(){ 
     // Some code... 
     RestTemplate rt = restTemplateComponentFix.getRestTemplate(); 
     // Some code... 
    } 
} 

Danach können Sie Unit-Test mit so etwas wie:

RestTemplate rt = Mockito.mock(RestTemplate.class) 
when(restTemplateComponentFix.getRestTemplate()).thenReturn(rt); 
when(rt.someMethod()).thenReturn(something);