6

Pracuję nad aplikacją klienta Spring Boot Eureka z obsługą równoważenia obciążenia wstążkami.Wstążka z chmurą wiosenną i Eureka: java.lang.IllegalStateException: Brak dostępnych instancji dla Samarths-MacBook-Pro.local

Mam dwa wystąpienia serwera zarejestrowanego w Eureka o nazwie "TEST". Po stronie klienta mam następujący kod do pobrania serwera z Eureka.

@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}} 

Jednak, kiedy uderzyć końcowy spokojny curl http://localhost:8090/, to daje mi następujący błąd: "wyjątek": "java.lang .IllegalStateException "," message ":" org.springframework.web.util.NestedServletException: Przetwarzanie żądania nie powiodło się, wyjątek zagnieżdżony to java.lang.IllegalStateException: Brak dostępnych instancji dla Samarths-MacBook-Pro.local "," 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 

Wygląda na mojej liście serwerów jest pusta.

Odpowiedz

7

Autoryzowany przez RestTemplate jest już podłączony do Wstążki. Wykonuje się więc wyszukiwanie ręcznie, a następnie RestTemplate próbuje wyszukać nazwę hosta przekazaną na wstążkę. Dostępne są dwie opcje: 1) Nie używaj netflix DiscoveryClient i przekazuj identyfikator serviceId jako logiczną nazwę hosta na wstążce (http://TEST/myservice), 2) Nie używaj automatycznego nagrywania RestTemplate, utwórz nowy dla swojej klasy. Mój wybór byłby # 1.

+0

Dzięki za sugestię. Użyłem odmiany twojego pierwszego wyboru, aby naprawić mój problem. – Samarth

+0

Łącze do dokumentacji: http: //projects.spring.io/spring-cloud/spring-cloud.html#_spring_resttemplate_as_a_load_balancer_client –

4

Mam to działa. Jedyną zmianą, którą musiałem wprowadzić, było to, w jaki sposób korzystałem z apletu RestTemplate.

Kod błędu:

@Autowired 
RestTemplate restTemplate; 

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

    return baseDir; 
} 

Kodeks pracy:

@Autowired 
RestTemplate restTemplate; 

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

    return baseDir; 
} 

Rozwiązanie:

Pierwszym parametrem restTemplate.getForObject powinien mieć format adresu URL. Nazwa domeny powinna być nazwą usługi, którą chcesz odkryć.

Np .: http://TEST. W tym miejscu TEST to nazwa mojego serwera zarejestrowanego w rejestrze eureka

+1

Tak, to jest to, co powiedziałem, że musisz zrobić. – spencergibb

1

Na to pytanie już udzielono odpowiedzi, ale znalazłem rozwiązanie, które wydaje się zadbane i naprawiło nasz problem.

Najpierw zadeklarować nową klasę @Component aw nim stworzyć metodę, która zwraca RestTemplate:

@Component 
public class RestTemplateComponentFix{ 

@Autowired 
SomeConfigurationYouNeed someConfiguration; 

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

} 

Po tym tylko Autowire się restTemplateComponentFix w swojej klasie i podczas gdy trzeba szablon odpoczynku nazywamy restTemplate() metoda.Coś takiego:

@Service 
public class someClass{ 

    @Autowired 
    RestTemplateComponentFix restTemplateComponentFix; 

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

Po tym można testów jednostkowych z czymś takim jak ty:

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