2016-12-30 182 views
6

我正在尝试使用Feign客户端。下面是我的feing客户端:负载均衡器没有可用的客户端服务器

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.spring[email protected]547496c2: startup date [Fri Dec 30 13:07:17 EST 2016]; parent: org.springframework.boot[email protected]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:[email protected] 
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上找到任何有关此信息。我也找不到discussion thread on StackOverflow的任何信息。

我在这里错过了什么? TIA。

更多详情:

application.yml对电影-API的microService是如下:电影API模块上

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

春天启动的应用程序:

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

您使用的是服务发现如尤里卡或领事?如果是这样,你是否已经在Spring Boot应用程序的application.yml中定义了配置,将该应用程序注册为Eureka的客户端?基本上,Feign抱怨说它找不到在任何地方注册过的服务。您可以使用Spring Cloud轻松配置像Eureka这样的服务发现。请参阅http://projects.spring.io/spring-cloud/ – Bloodysock

+1

@Bloodysock那么我应该使用发现服务的哪一方?在客户端或api端? –

+1

您将注册您的API(更好的术语将是“服务”),并为服务发现指定一个唯一的名称。客户端只需发现服务并调用它。 Spring Cloud使开发人员更容易,特别是Spring Boot。阅读上面链接的站点上记录的示例。您将在15分钟内完成服务电话:) – Bloodysock

回答

13

经过研究,在@Bloodysock的帮助下,我发现我在'client-app'微服务中缺少远程服务器的注册。该文件在Spring Cloud Netflix

我用丝带没有尤里卡用在“client-app”微服务为application.yml配置:

movie-api: 
    ribbon: 
    listOfServers: http://localhost:8090 
相关问题