web-dev-qa-db-ja.com

ロードバランサーにクライアントで使用可能なサーバーがありません

Feignクライアントを使用しようとしています。以下は私のクライアントです:

import com.eprogrammerz.examples.domain.Movie;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Created by Yogen on 12/26/2016.
 */
@FeignClient(name = "movie-api")
public interface MovieApi {
    @RequestMapping(method = RequestMethod.GET, value = "/movies/{id}")
    Movie getMovie(@PathVariable("id") Long id);
}

私は以下のように簡単なサービスからそれを呼び出しています:

@Service
public class MovieService {

    @Autowired
    MovieApi movieApi;

    public Movie findMovie(Long id){
        Movie movieOfTheDay = movieApi.getMovie(id);
        return movieOfTheDay;
    }
}

私の春のブートアプリは次のとおりです:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@EnableFeignClients(basePackages = {"com.eprogrammerz.examples"})
@EnableCircuitBreaker
@SpringBootApplication
public class ClientAppApplication {

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

build.gradle

buildscript {
    ext {
        springBootVersion = '1.4.3.RELEASE'
    }
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'Java'
apply plugin: 'Eclipse'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'client-app'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    jcenter()
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}


dependencies {
    compile('org.springframework.cloud:spring-cloud-starter-feign')
    // https://mvnrepository.com/artifact/com.netflix.hystrix/hystrix-core
    compile('org.springframework.cloud:spring-cloud-starter-hystrix')
    compile("org.springframework.boot:spring-boot-starter-web"){
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.BUILD-SNAPSHOT"
        mavenBom "org.springframework.boot:spring-boot-starter-parent:${springBootVersion}"
    }
}

次のようにエラーが発生しています:

2016-12-30 13:07:16.894  INFO 6748 --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 39 ms
2016-12-30 13:07:16.939  INFO 6748 --- [nio-8082-exec-1] c.e.e.controllers.RequestController      : Calling findMovie(1203)
2016-12-30 13:07:17.240  INFO 6748 --- [rix-movie-api-1] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@547496c2: startup date [Fri Dec 30 13:07:17 EST 2016]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@542e560f
2016-12-30 13:07:17.318  INFO 6748 --- [rix-movie-api-1] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-12-30 13:07:17.619  INFO 6748 --- [rix-movie-api-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: movie-api.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2016-12-30 13:07:17.670  INFO 6748 --- [rix-movie-api-1] c.n.u.concurrent.ShutdownEnabledTimer    : Shutdown hook installed for: NFLoadBalancer-PingTimer-movie-api
2016-12-30 13:07:17.727  INFO 6748 --- [rix-movie-api-1] c.netflix.loadbalancer.BaseLoadBalancer  : Client:movie-api instantiated a LoadBalancer:DynamicServerListLoadBalancer:{NFLoadBalancer:name=movie-api,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2016-12-30 13:07:17.739  INFO 6748 --- [rix-movie-api-1] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
2016-12-30 13:07:17.746  INFO 6748 --- [rix-movie-api-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client movie-api initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=movie-api,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@45bcfd5
2016-12-30 13:07:18.191 ERROR 6748 --- [nio-8082-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 com.netflix.hystrix.exception.HystrixRuntimeException: MovieApi#getMovie(Long) failed and no fallback available.] with root cause

com.netflix.client.ClientException: Load balancer does not have available server for client: movie-api
    at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.Java:468) ~[ribbon-loadbalancer-2.2.0.jar:2.2.0]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.Java:184) ~[ribbon-loadbalancer-2.2.0.jar:2.2.0]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.Java:180) ~[ribbon-loadbalancer-2.2.0.jar:2.2.0]
    at rx.Observable.unsafeSubscribe(Observable.Java:10211) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.Java:94) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.Java:42) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.unsafeSubscribe(Observable.Java:10211) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.Java:127) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.Java:73) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.Java:52) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.Java:79) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.Java:45) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.Java:276) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Subscriber.setProducer(Subscriber.Java:209) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.Java:138) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.Java:129) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.subscribe(Observable.Java:10307) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.subscribe(Observable.Java:10274) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.Java:445) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.observables.BlockingObservable.single(BlockingObservable.Java:342) ~[rxjava-1.1.10.jar:1.1.10]
    at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.Java:102) ~[ribbon-loadbalancer-2.2.0.jar:2.2.0]
    at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.Java:63) ~[spring-cloud-netflix-core-1.2.4.BUILD-SNAPSHOT.jar:1.2.4.BUILD-SNAPSHOT]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.Java:97) ~[feign-core-9.3.1.jar:na]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.Java:76) ~[feign-core-9.3.1.jar:na]
    at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.Java:108) ~[feign-hystrix-9.3.1.jar:na]
    at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.Java:301) ~[hystrix-core-1.5.6.jar:1.5.6]
    at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.Java:297) ~[hystrix-core-1.5.6.jar:1.5.6]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.Java:46) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.Java:35) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.unsafeSubscribe(Observable.Java:10211) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.Java:51) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.Java:35) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.unsafeSubscribe(Observable.Java:10211) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.Java:41) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:48) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.Java:30) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.Observable.unsafeSubscribe(Observable.Java:10211) ~[rxjava-1.1.10.jar:1.1.10]
    at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.Java:94) ~[rxjava-1.1.10.jar:1.1.10]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.Java:56) ~[hystrix-core-1.5.6.jar:1.5.6]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.Java:47) ~[hystrix-core-1.5.6.jar:1.5.6]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.Java:69) ~[hystrix-core-1.5.6.jar:1.5.6]
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.Java:55) ~[rxjava-1.1.10.jar:1.1.10]
    at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:511) ~[na:1.8.0_51]
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:266) ~[na:1.8.0_51]
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142) ~[na:1.8.0_51]
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617) ~[na:1.8.0_51]
    at Java.lang.Thread.run(Thread.Java:745) [na:1.8.0_51]

私は別の方法を試しました。しかし、解決策を理解できませんでした。 Spring Cloud Netflix でもこれに関する情報が見つかりませんでした。 StackOverflowのディスカッションスレッド に関する情報も見つかりませんでした。

ここで何が欠けていますか? TIA。

詳細:

movie-apiマイクロサービスのapplication.ymlは次のとおりです。

server:
  port: 8090
logging:
  config: classpath:log4j2.yml
spring:
  application:
    name: movie-api

Movie-apiモジュールのSpringブートアプリ:

@SpringBootApplication
public class MovieApiApplication {

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

そしてコントローラーは次の通りです:

@RestController
@Slf4j
public class MovieController {
    @Autowired
    private MovieRepository movieRepository;

    @RequestMapping("/movies/{id}")
    public ResponseEntity<Movie> getBook(@PathVariable("id") Long id){
        log.trace("getBook({})",id);
        Optional<Movie> movie = Optional.of(movieRepository.findOneById(id));
        if(movie.isPresent())
            return new ResponseEntity(movie.get(), HttpStatus.OK);
        return new ResponseEntity<Movie>(HttpStatus.NOT_FOUND);
    }
}
16
Yogen Rai

調査を行った後、@ Bloodysockの助けを借りて、「client-app」マイクロサービスのリモートサーバーの登録が欠落していることがわかりました。ドキュメントは Spring Cloud Netflix にあります。

'application.yml'マイクロサービスのclient-appの構成でEurekaなしのリボンを使用しました:

movie-api:
  ribbon:
    listOfServers: http://localhost:8090
23
Yogen Rai

問題は、サービスが要求されたサービスのホストを知らないことです。 Eurekaを使用している場合、.propertiesファイルまたは.ymlファイルに次の行を追加します。

eureka.client.fetchRegistry=true

OR

eureka:
    client:
        fetchRegistry: true

サービスがユーレカと話し、要求されたサービスのホストを検出します。

9
Luciano Nery

Spring Cloudのセットアップがapplication.properties/ application.ymlでのサーバーの指定をサポートしていない場合、構成クラスでサービスURLを構成する必要があります。

Pls、警告メッセージに注意してください私のapplication.properties [春ブートv2.0.0リリース、春-cloud-starter-feign&spring-cloud-starter-ribbon v 1.4.3.RELEASE]

enter image description here

だから私がやったことは、次のようにConfigurationクラスを書くことでした:

@Configuration
class LocalRibbonClientConfiguration {
    @Bean
    public ServerList<Server> ribbonServerList() {
        // return new ConfigurationBasedServerList();
        StaticServerList<Server> staticServerList = new StaticServerList<>((new Server("localhost", 8001)),
                new Server("localhost", 8000));
        return staticServerList;
    }
}

次に、この構成を次のように使用するようにSpring Bootアプリケーションを構成しました。

@SpringBootApplication
@EnableFeignClients("my-package.currencyconversionservice")
@RibbonClient(name = "currency-conversion-service", configuration = LocalRibbonClientConfiguration.class)
public class CurrencyConversionServiceApplication {
 // nothing new here...
}

Feign Proxyクラスを変更する必要はありません。問題の完全な解決策として役立つこの投稿のためだけに投稿する:

@FeignClient(name="currency-exchange-service")
@RibbonClient(name="currency-exchange-service")
public interface CurrencyExchangeServiceProxy {
    @GetMapping("/currency-exchange/from/{from}/to/{to}")
    public CurrencyConversionBean retrieveExchangeValue(@PathVariable("from") String from, @PathVariable("to") String to);
}

それで全部です。問題は修正されました。

2
Dexter

根本原因を見つけるために2時間も無駄にしました。クライアントアプリケーションにEnableEurekaClientを誤ってインポートしましたが、これが問題の根本原因でした。インポートを削除することで、最終的にこの問題を解決しました。驚いたことに、@ EnableDiscoveryClientは以下の依存関係を必要としません。ただし、Eureka Namingサーバーを使用している場合は、これを使用する必要があります。

   <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.0.0.RELEASE</version>
    </dependency>
1
CodeRider

Ribbionクライアントが正しいことを確認してください。

package com.in28minutes.microservices.currencyconversionservice;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;


@FeignClient(name="currency-exchange-service")
@RibbonClient(name="currency-exchange-service") 
public interface CurrencyExchangeServiceProxy {


    @GetMapping("/currency-exchange/from/{from}/to/{to}")
    public CurrencyConversionBean retrieveExchangeValue
        (@PathVariable("from") String from, @PathVariable("to") String to); //mention correct pathvariables
}
0
shubham kumar