zoukankan      html  css  js  c++  java
  • load balancer does not have available server for client: provider

    I'm trying to use Feign client. Below is my feing client:

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

    I'm calling it from simple service as below:

    @Service
    public class MovieService {
    
        @Autowired
        MovieApi movieApi;
    
        public Movie findMovie(Long id){
            Movie movieOfTheDay = movieApi.getMovie(id);
            return movieOfTheDay;
        }
    }

    My spring boot app is as below:

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

    I'm getting error as below:

    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@45bcfd52016-12-3013: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]

    I tried different way. But couldn't figure out the solution. I couldn't find any information about this on Spring Cloud Netflix too. I couldn't find any information on discussion thread on StackOverflow too.

    What I'm missing here? TIA.

    Further Details:

    application.yml for movie-api microservice is as below:

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

    Spring boot app on movie-api module:

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

    And controller is as below:

    @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);
        }
    }
    • 1
      Are you using a service discovery such as Eureka or Consul? If so, have you defined the configuration in your Spring Boot app's application.yml to register the app as a client to Eureka? Basically, Feign is complaining that it could not find the service registered anywhere. You can very easily configure a service discovery like Eureka using Spring Cloud. See projects.spring.io/spring-cloud – Bloodysock Dec 30 '16 at 22:37
    • 1
      @Bloodysock so on which side should i use discovery service? Here on client side or api side? – Yogen RaiJan 1 '17 at 2:09
    • 1
      You'd register your API (better term would be "service") with a unique name to the service discovery. The client simply discovers the service and invokes it. Spring Cloud makes it real easy for the developer especially with Spring Boot. Go through the example documented at the site I linked above. You will on your way making the service calls in 15 minutes :) – Bloodysock Jan 1 '17 at 16:04
    •  
      @Bloodysock yes you are right! i was missing 'service' registration. Thank you!. – Yogen Rai Jan 3 '17 at 6:44

    3 Answers

    After doing research, and with help of @Bloodysock, I found that I was missing registration of remote server in 'client-app' micro-service. The document is at Spring Cloud Netflix.

    I used Ribbon without Eureka with configuration in application.yml in 'client-app' micro-service as:

    movie-api:
      ribbon:
        listOfServers: http://localhost:8090
     

    The problem is that your service doesn't know the host of requested service. If you are using Eureka, put this line on your .properties or .yml file:

    eureka.client.fetchRegistry=true

    OR

    eureka: client: fetchRegistry: true

    It'll make your service talk with Eureka and discovers host of requested service.

    If you Spring Cloud set up does not support specifying the servers in application.properties/application.yml, you have to configure the services URL in a Configuration class.

    Pls, note the warning message in my application.properties [Spring Boot v2.0.0RELEASE, spring-cloud-starter-feign & spring-cloud-starter-ribbon v 1.4.3.RELEASE]

    enter image description here

    So what I did was to write a Configuration class as follows:

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

    Then, configured the Spring Boot Application to use this configuration as follows:

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

    No need to change the Feign Proxy class. Posting just for this post to be served as a complete solution to the problem:

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

    That's all. The problem was fixed.

  • 相关阅读:
    【转】Android之四大组件、六大布局、五大存储
    Android O 8.0 奥利奥
    安卓7.1新特性
    那些年我们踩过的坑,SQL 中的空值陷阱!
    8年经验面试官详解 Java 面试秘诀
    Github 第三方授权登录教程
    40个超有趣的Linux命令行彩蛋和游戏
    Synchronized锁在Spring事务管理下,为啥还线程不安全?
    Windows Server 2008 R2文件服务器升级到Windows Server 2016
    牛客练习赛61
  • 原文地址:https://www.cnblogs.com/lykbk/p/dfgfdgdfdg546546456.html
Copyright © 2011-2022 走看看