我试图将Hystrix添加到我的应用程序中,该应用程序侦听(@SqsListener)队列(Amazon SQS)并执行消息操作。
该代码适用于RestController,但我的监听器无法获得相同的行为。
@EnableCircuitBreaker
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@PreDestroy
public void hystrixCleanup() {
Hystrix.reset();
}
}
@Slf4j
@Component
@RequiredArgsConstructor
public class QueueListener {
private final SampleService sampleService;
@SqsListener(value = "sample-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void receiveMsg(String payload, Acknowledgment acknowledgment) {
SampleResponse sampleResponse = sampleService.getSampleResponse(payload);
log.info(sampleResponse.getMessage());
acknowledgment.acknowledge();
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SampleResponse {
private String message;
}
@Service
@DefaultProperties(raiseHystrixExceptions = {RUNTIME_EXCEPTION})
public class SampleService {
@HystrixCommand(commandKey = "getSampleResponse")
public SampleResponse getSampleResponse(String value) {
if ("123".equals(value)) {
throw new SampleException("123");
}
return new SampleResponse(value);
}
}
@Slf4j
@ControllerAdvice
public class SampleExceptionHandler {
@ExceptionHandler({ HystrixRuntimeException.class })
// public ResponseEntity<SampleResponse> handleHystrixRuntimeException(HystrixRuntimeException exception) {
public void handleHystrixRuntimeException(HystrixRuntimeException exception) {
String newMsg;
if (exception.getFailureType() == TIMEOUT) {
newMsg = "Timeout Error: ".concat(exception.getMessage());
} else {
if (exception.getCause() instanceof SampleException) {
newMsg = "Sample Exception: ".concat(exception.getCause().getMessage());
} else {
newMsg = "Server Error: ".concat(exception.getMessage());
}
}
log.error("Hystrix Exception: {}", newMsg);
// return new ResponseEntity<>(new SampleResponse(newMsg), HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler({ SampleException.class })
public void handleSampleException(SampleException exception) {
log.error("Sample Exception: {}", exception.getMessage());
}
}
示例代码可在此处找到:https://github.com/Niranjan-K/spring-samples/tree/sqs-hystrix
对控制器(http://localhost:8080/hello/123)进行Get调用时,它将按预期方式命中ExceptionHandler.class。但是,当消息“ 123”发布到队列时,不会发生这种情况。 Controller和Listener类都调用相同的服务类(和相同的方法)。
下面是进行rest调用时的日志:
2019-06-11 14:46:57.189错误55399 --- [nio-8080-exec-1] o.n.s.s.h.h.SampleExceptionHandler:Hystrix异常:示例异常:123
在SqsListener的情况下:
2019-06-11 14:47:35.117错误55399 --- [enerContainer-2] o.s.c.a.m.listener.QueueMessageHandler:消息处理程序方法未处理的异常
com.netflix.hystrix.exception.HystrixRuntimeException:getSampleResponse失败并且回退失败。 在com.netflix.hystrix.AbstractCommand $ 22.call(AbstractCommand.java:832)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.AbstractCommand $ 22.call(AbstractCommand.java:807)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.internal.operators.OperatorOnErrorResumeNextViaFunction $ 4.onError(OperatorOnErrorResumeNextViaFunction.java:140)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在com.netflix.hystrix.AbstractCommand $ DeprecatedOnFallbackHookApplication $ 1.onError(AbstractCommand.java:1472)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.AbstractCommand $ FallbackHookApplication $ 1.onError(AbstractCommand.java:1397)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.observers.Subscribers $ 5.onError(Subscribers.java:230)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OperatorOnErrorResumeNextViaFunction $ 4.onError(OperatorOnErrorResumeNextViaFunction.java:142)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在com.netflix.hystrix.AbstractCommand $ HystrixObservableTimeoutOperator $ 3.onError(AbstractCommand.java:1194)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.internal.operators.OperatorSubscribeOn $ SubscribeOnSubscriber.onError(OperatorSubscribeOn.java:80)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.observers.Subscribers $ 5.onError(Subscribers.java:230)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach $ DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.observers.Subscribers $ 5.onError(Subscribers.java:230)〜[rxjava-1.3.8.jar!/:1.3.8] com.netflix.hystrix.AbstractCommand $ DeprecatedOnRunHookApplication $ 1.onError(AbstractCommand.java:1431)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.AbstractCommand $ ExecutionHookApplication $ 1.onError(AbstractCommand.java:1362)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.observers.Subscribers $ 5.onError(Subscribers.java:230)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.observers.Subscribers $ 5.onError(Subscribers.java:230)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.Observable.unsafeSubscribe(Observable.java:10327)〜[rxjava-1.3.8.jar!/:1.3.8] 在rx.internal.operators.OperatorSubscribeOn $ SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)〜[rxjava-1.3.8.jar!/:1.3.8] 在com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction $ 1.call(HystrixContexSchedulerAction.java:56)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction $ 1.call(HystrixContexSchedulerAction.java:47)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)〜[rxjava-1.3.8.jar!/:1.3.8] 在java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)〜[na:1.8.0_181] 在java.util.concurrent.FutureTask.run(FutureTask.java:266)〜[na:1.8.0_181] 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[na:1.8.0_181] 在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)[na:1.8.0_181] 在java.lang.Thread.run(Thread.java:748)[na:1.8.0_181] 引起原因:org.nira.sample.sqs.hystrix.exception.SampleException:123 在org.nira.sample.sqs.hystrix.service.SampleService.getSampleResponse(SampleService.java:18)〜[classes!/:1.0-SNAPSHOT] 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_181] 在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_181] 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_181] 在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_181] 在com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.execute(MethodExecutionAction.java:116)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.executeWithArgs(MethodExecutionAction.java:93)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.execute(MethodExecutionAction.java:78)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.contrib.javanica.command.GenericCommand $ 1.execute(GenericCommand.java:48)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand.process(AbstractHystrixCommand.java:145)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.contrib.javanica.command.GenericCommand.run(GenericCommand.java:45)〜[hystrix-javanica-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.HystrixCommand $ 2.call(HystrixCommand.java:302)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在com.netflix.hystrix.HystrixCommand $ 2.call(HystrixCommand.java:298)〜[hystrix-core-1.5.18.jar!/:1.5.18] 在rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)〜[rxjava-1.3.8.jar!/:1.3.8] ...省略了26个共同的框架