2016-12-30 9 views
6

Próbuję użyć klienta Feign. Poniżej jest mój klient feing:System równoważenia obciążenia nie ma dostępnego serwera dla klienta

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

Wołam go od prostej usługi jak poniżej:

@Service 
public class MovieService { 

    @Autowired 
    MovieApi movieApi; 

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

buta wiosna aplikacja jest jak poniżej:

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

Otrzymuję błąd, jak poniżej:

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] 

Próbowałem inaczej. Ale nie potrafił znaleźć rozwiązania. Nie mogłem znaleźć żadnych informacji na ten temat również na Spring Cloud Netflix. Nie mogłem znaleźć również informacji na temat discussion thread on StackOverflow.

Czego mi tu brakuje? TIA.

Dodatkowe szczegóły:

application.yml za film-api microservice jest jak poniżej:

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

Wiosna rozruchu app moduł movie-API:

@SpringBootApplication 
public class MovieApiApplication { 

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

i kontrolera jest jako poniżej:

@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

Czy używasz wykrywania usług, takich jak EUREKA lub konsula? Jeśli tak, to czy zdefiniowałeś konfigurację w aplikacji Spring.ot app.yml, aby zarejestrować aplikację jako klienta w Eureka? Zasadniczo Feign skarży się, że nie może znaleźć usługi zarejestrowanej w dowolnym miejscu. Możesz bardzo łatwo skonfigurować wykrywanie usług, takie jak Eureka przy użyciu Spring Cloud. Zobacz http://projects.spring.io/spring-cloud/ – Bloodysock

+1

@Bloodysock, po której stronie powinienem skorzystać z usługi wykrywania? Tutaj po stronie klienta lub po stronie interfejsu API? –

+1

Użytkownik zarejestrowałby swój interfejs API (lepszym terminem będzie "usługa") o unikalnej nazwie dla usługi wykrywania. Klient po prostu odkrywa usługę i ją wywołuje. Spring Cloud sprawia, że ​​programista jest bardzo łatwy w obsłudze, szczególnie w Spring Boot. Przejdź przez przykład udokumentowany na stronie, którą podałem powyżej. Będziesz na swój sposób wykonywać połączenia serwisowe w 15 minut :) – Bloodysock

Odpowiedz

13

Po przeprowadzeniu badań i przy pomocy @Bloodysock, stwierdziłem, że brakowało mi rejestracji zdalnego serwera w mikroserwisie "aplikacja kliencka". Dokument znajduje się pod numerem Spring Cloud Netflix.

użyłem Ribbon bez Eureka z konfiguracją w application.yml w „client-app” mikro-usługi, jak:

movie-api: 
    ribbon: 
    listOfServers: http://localhost:8090 
Powiązane problemy