web-dev-qa-db-ja.com

Spring CloudおよびEurekaのリボン:Java.lang.IllegalStateException:Samarths-MacBook-Pro.localで使用できるインスタンスはありません

リボンロードバランサーを備えたSpring Boot Eurekaクライアントアプリケーションに取り組んでいます。

"TEST"という名前でEurekaに登録されたサーバーの2つのインスタンスがあります。クライアント側では、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}}

ただし、次のコマンドを使用してレストフルエンドポイントにアクセスすると、エラーが発生します。

curl http://localhost:8090/

これはエラーです:

{"exception":"Java.lang.IllegalStateException","message":"org.springframework.web.util.NestedServletException: Request processing failed; nested exception is Java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local","path":"/"}

スタックトレース:

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.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@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

サーバーリストが空のようです。

13
Samarth

自動配線したRestTemplateはすでにリボンに接続されています。したがって、手動でルックアップを実行すると、RestTemplateはリボンに渡されたホスト名をルックアップしようとします。 2つのオプションがあります。1)netflix DiscoveryClientを使用せず、serviceIdを論理ホスト名としてリボン(http://TEST/myservice)、2)自動配線されたRestTemplateを使用せず、クラス用に新しいものを作成します。私の選択は#1でしょう。

19
spencergibb

私はこれを手に入れました。私がしなければならない唯一の変更は、RestTemplate APIの使用方法でした。

エラーコード:

@Autowired
RestTemplate restTemplate;

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

    return baseDir;
}

作業コード:

@Autowired
RestTemplate restTemplate;

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

    return baseDir;
}

解決:

RestTemplate.getForObjectの最初のパラメーターは、URLの形式にする必要があります。また、ドメイン名は、検出するサービスの名前である必要があります。

例: http:// TEST 。ここで、TESTは、eurekaレジストリに登録されているサーバーの名前です。

6
Samarth

質問はすでに回答されていますが、問題を解決するための適切な回避策を見つけました。

最初に新しい@Componentクラスを宣言し、その中にRestTemplateを返すメソッドを作成します。

@Component
public class RestTemplateComponentFix{

 @Autowired
 SomeConfigurationYouNeed someConfiguration;

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

}

その後、クラスのrestTemplateComponentFixをAutowireし、残りのテンプレートが必要なときにrestTemplate()メソッドを呼び出します。このようなもの:

@Service
public class someClass{

    @Autowired
    RestTemplateComponentFix restTemplateComponentFix;

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

その後、次のようなものでユニットテストを行うことができます:

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