gpt4 book ai didi

spring - @FeignClient 不退缩

转载 作者:行者123 更新时间:2023-12-02 02:44:09 25 4
gpt4 key购买 nike

我正在尝试了解 Spring Boot 和 Hystrix,但无法让后备方法发挥作用。我尝试了两种方法,@HystrixCommand@FeignClient。我可以获取 @HystrixCommand,但不能获取 @FeignClient。大部分代码都是基于我在搜索时看到的示例,所以我认为我非常接近,但一定遗漏了一些关键的东西。

这是 Spring Boot 应用程序和 REST Controller 。我正在同一个应用程序中尝试这两种方法。它正在向 Eureka 注册。我没有运行 hello-world 服务,因此它应该始终回退。

package com.example.goodBye.service;

@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
@SpringBootApplication
public class GoodByeServiceApplication {

private final static AtomicInteger counter = new AtomicInteger();
private final static Logger logger = LoggerFactory.getLogger(GoodByeServiceApplication.class);

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

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}

@RefreshScope
@RestController
class MessageController {

@Autowired
private HelloClient helloClient;

@Autowired
private HelloService helloService;

@Value("${message:Good Bye Default}")
private String message;

@RequestMapping(value = "/message", produces = "application/json")
public Message getMessage(@RequestParam(value = "name", defaultValue = "Anonymous") String name) {
return new Message(counter.incrementAndGet(), String.format("%s from %s", this.message, name));
}

@RequestMapping(value = "/hello", produces = "application/json")
public Message sayHello(@RequestParam(value = "name", defaultValue = "Creepy") String name) {
Message hello = helloService.sayHello(name);

return new Message(counter.incrementAndGet(), String.format("%s/%s from %s", hello.getMessage(), message, name));
}

@RequestMapping(value = "/helloAgain", produces = "application/json")
public Message sayHelloAgain(@RequestParam(value = "name", defaultValue = "Creepy") String name) {
Message hello = helloClient.sayHello(name);

return new Message(counter.incrementAndGet(), String.format("%s/%s from %s", hello.getMessage(), message, name));
}

}

static class Message {

private int count;
private String message;

public Message() {
}

public Message(int count, String message) {
this.count = count;
this.message = message;
}

public int getCount() {
return count;
}

public String getMessage() {
return message;
}

}

}

这是使用 @HystrixCommand 进行的尝试,确实有效。当我在后备方法中放置断点时,我确实在调用堆栈中看到了 Hystrix。

@Service
class HelloService {

@Autowired
private DiscoveryClient discoveryClient;

@Autowired
private RestTemplate restTemplate;

@HystrixCommand(fallbackMethod = "rude")
public Message sayHello(String name) {
Message ret = null;

List<ServiceInstance> instances = discoveryClient.getInstances("hello-world");
...
ResponseEntity<Message> resp = restTemplate.getForEntity(uri, Message.class, params);
ret = resp.getBody();

return ret;
}

public Message rude(String name) {
return new Message(counter.incrementAndGet(), String.format("%s was rather rude!", name));
}

}

这是使用 @FeignClient 进行的尝试,但不起作用。程序抛出 com.netflix.client.ClientException: Load Balancer does not have available server for client: hello-world 并且调用堆栈不包含任何 Hystrix 类。

@FeignClient(value = "hello-world", fallback = HelloClientFallback.class)
interface HelloClient {

@RequestMapping(value = "/message", method = RequestMethod.GET)
public Message sayHello(String name);

}

@Component
class HelloClientFallback implements HelloClient {

@Override
public Message sayHello(String name) {
return new Message(counter.incrementAndGet(), String.format("%s is not much better", name));
}

}

如果有任何帮助,我将不胜感激。这可能是一些愚蠢的东西,但我已经盯着它看了太久了,却没有看到它。

谢谢,韦斯。

这是失败的调用堆栈,以防有帮助。

com.netflix.client.ClientException: Load balancer does not have available server for client: hello-world
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
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:117) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63) ~[spring-cloud-netflix-core-1.3.0.RC1.jar:1.3.0.RC1]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97) ~[feign-core-9.4.0.jar:na]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-9.4.0.jar:na]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-9.4.0.jar:na]
at com.example.goodBye.service.$Proxy108.sayHello(Unknown Source) ~[na:na]
at com.example.goodBye.service.GoodByeServiceApplication$MessageController.sayHelloAgain(GoodByeServiceApplication.java:79) ~[main/:na]

这是成功的调用堆栈,但并没有真正揭示任何有用的信息,因为 Hystrix 运行在不同的线程中。

java.lang.IllegalStateException: Call stack of successful fallback
at com.example.goodBye.service.GoodByeServiceApplication$HelloService.rude(GoodByeServiceApplication.java:147) ~[main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
at com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.execute(MethodExecutionAction.java:116) [hystrix-javanica-1.5.10.jar:1.5.10]
at com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.executeWithArgs(MethodExecutionAction.java:93) [hystrix-javanica-1.5.10.jar:1.5.10]
at com.netflix.hystrix.contrib.javanica.command.GenericCommand$2.execute(GenericCommand.java:76) [hystrix-javanica-1.5.10.jar:1.5.10]
at com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand.process(AbstractHystrixCommand.java:145) [hystrix-javanica-1.5.10.jar:1.5.10]
at com.netflix.hystrix.contrib.javanica.command.GenericCommand.getFallback(GenericCommand.java:71) [hystrix-javanica-1.5.10.jar:1.5.10]
at com.netflix.hystrix.HystrixCommand$3.call(HystrixCommand.java:322) [hystrix-core-1.5.10.jar:1.5.10]
at com.netflix.hystrix.HystrixCommand$3.call(HystrixCommand.java:318) [hystrix-core-1.5.10.jar:1.5.10]
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.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.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.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.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.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.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:142) [rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) [rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) [rxjava-1.1.10.jar:1.1.10]
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$3.onError(AbstractCommand.java:1194) [hystrix-core-1.5.10.jar:1.5.10]
at rx.internal.operators.OperatorSubscribeOn$1$1.onError(OperatorSubscribeOn.java:59) [rxjava-1.1.10.jar:1.1.10]
at rx.observers.Subscribers$5.onError(Subscribers.java:230) [rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) [rxjava-1.1.10.jar:1.1.10]
at rx.observers.Subscribers$5.onError(Subscribers.java:230) [rxjava-1.1.10.jar:1.1.10]
at com.netflix.hystrix.AbstractCommand$DeprecatedOnRunHookApplication$1.onError(AbstractCommand.java:1431) [hystrix-core-1.5.10.jar:1.5.10]
at com.netflix.hystrix.AbstractCommand$ExecutionHookApplication$1.onError(AbstractCommand.java:1362) [hystrix-core-1.5.10.jar:1.5.10]
at rx.observers.Subscribers$5.onError(Subscribers.java:230) [rxjava-1.1.10.jar:1.1.10]
at rx.observers.Subscribers$5.onError(Subscribers.java:230) [rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44) [rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28) [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.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.10.jar:1.5.10]
at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:47) [hystrix-core-1.5.10.jar:1.5.10]
at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69) [hystrix-core-1.5.10.jar:1.5.10]
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_45]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]

最佳答案

您的日志显示您正在使用 Spring Cloud Netflix 1.3.0RC1。从这个版本开始,FeignClient 不再使用 HystrixCommand 包装方法。如果 hystrix 不存在,则需要在类路径上添加它并设置选项 feign.hystrix.enabled=true。

Feign clients no longer wrap methods in Hystrix commands by default (#1277). You must have Hystrix on the classpath and also set feign.hystrix.enabled=true to have Feign automatically wrap methods in Hystrix commands.

请参阅发行说明。 https://github.com/spring-projects/spring-cloud/wiki/Spring-Cloud-Dalston-Release-Notes

关于spring - @FeignClient 不退缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43401758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com