我正在使用ReplyingKafkaTemplate
在两个微服务之间建立同步调用。
事件的接收者用SendTo
注释,如下所示:
@KafkaListener(topics = "${kafka.topic.prefix}"
+ "${kafka.topic.name}", containerFactory = "customEventKafkaListenerFactory")
@SendTo
public CustomResponseEvent onMessage(
@Payload @Valid CustomRequestEvent event, @Header(KafkaHeaders.CORRELATION_ID) String correlationId,
@Header(KafkaHeaders.REPLY_TOPIC) String replyTopic) {
//Making some REST API calls to another external system here using RestTemplate
}
REST API调用可以引发4xx或5xx。有许多这样的调用,有些是内部系统的调用,有些是外部系统的调用。这可能是一个糟糕的设计,但是我们不要陷入其中。
我想要一个RestTemplate
的全局异常处理程序,在这里我可以捕获所有异常,然后将响应返回给事件的原始发送者。
我正在使用与使用者收到的相同的replyTopic
和correlationId
来发布事件。
但是响应的接收者仍然会抛出No pending reply
异常。
答案 0 :(得分:1)
@KafkaListener
随附:
/**
* Set an {@link org.springframework.kafka.listener.KafkaListenerErrorHandler} bean
* name to invoke if the listener method throws an exception.
* @return the error handler.
* @since 1.3
*/
String errorHandler() default "";
该异常用于捕获和处理所有下游异常,如果返回异常,则将其发送回replyTopic
:
public void onMessage(ConsumerRecord<K, V> record, Acknowledgment acknowledgment, Consumer<?, ?> consumer) {
Message<?> message = toMessagingMessage(record, acknowledgment, consumer);
logger.debug(() -> "Processing [" + message + "]");
try {
Object result = invokeHandler(record, acknowledgment, message, consumer);
if (result != null) {
handleResult(result, record, message);
}
}
catch (ListenerExecutionFailedException e) { // NOSONAR ex flow control
if (this.errorHandler != null) {
try {
Object result = this.errorHandler.handleError(message, e, consumer);
if (result != null) {
handleResult(result, record, message);
}
}
catch (Exception ex) {
throw new ListenerExecutionFailedException(createMessagingErrorMessage(// NOSONAR stack trace loss
"Listener error handler threw an exception for the incoming message",
message.getPayload()), ex);
}
}
else {
throw e;
}
}
有关更多信息,请参见RecordMessagingMessageListenerAdapter
源代码。