15

私は、Ribbon Load Balancer を使用して Spring Boot Eureka Client Application に取り組んでいます。

「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);
    }
}

アプリケーション.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

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

4

6 に答える 6

25

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

于 2015-07-22T21:35:19.190 に答える
7

私はこれを機能させました。私がしなければならなかった唯一の変更は、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 レジストリに登録されている私のサーバーの名前です

于 2015-07-23T15:14:31.063 に答える
3

質問には既に回答がありますが、きちんとした回避策を見つけて問題を解決しました。

最初に新しい @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を自動配線し、残りのテンプレートが必要なときに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);
于 2017-11-10T10:28:13.687 に答える
0

@spencergibb の方法を試した後、 ..MS で使用できるインスタンスがないことにまだ苦労している場合は、@spencergibb によって既に質問に回答されています... Netflix Eureka を使用している場合は pom.xml で確認し、Netflix リボンの依存関係を追加しないようにしてください。エウレカ自体が内部でリボンを使用しているため。これは私にとって問題を引き起こしていました。

于 2021-09-20T20:03:44.150 に答える