我正在尝试为我的Spring Cloud Dataflow流创建一个自定义异常处理程序,以路由一些要重新排队的错误和其他要进行DLQ的错误。
为此,我利用了全局Spring Integration“ errorChannel”并根据异常类型进行路由。
这是Spring Integration错误路由器的代码:
package com.acme.error.router;
import com.acme.exceptions.DlqException;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.transformer.MessageTransformationException;
import org.springframework.messaging.Message;
@MessageEndpoint
@EnableBinding({ ErrorMessageChannels.class })
public class ErrorMessageMappingRouter {
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorMessageMappingRouter.class);
public static final String ERROR_CHANNEL = "errorChannel";
@Router(inputChannel = ERROR_CHANNEL)
public String onError(Message<Object> message) {
LOGGER.debug("ERROR ROUTER - onError");
if(message.getPayload() instanceof MessageTransformationException) {
MessageTransformationException exception = (MessageTransformationException) message.getPayload();
Message<?> failedMessage = exception.getFailedMessage();
if(exceptionChainContainsDlq(exception)) {
return ErrorMessageChannels.DLQ_QUEUE_NAME;
}
return ErrorMessageChannels.REQUEUE_CHANNEL;
}
return ErrorMessageChannels.DLQ_QUEUE_NAME;
}
...
}
每个流应用通过Spring Boot App上的程序包扫描为每个流应用选择错误路由器:
@ComponentScan(basePackages = { "com.acme.error.router" }
@SpringBootApplication
public class StreamApp {}
当将其部署并与本地Spring Cloud Dataflow服务器(版本1.5.0-RELEASE)一起运行并引发DlqException时,该消息已成功路由到errorRouter中的onError方法,然后放入dlq主题中
但是,当将其作为带有SCDF Kubernetes服务器(也是1.5.0-RELEASE版本)的docker容器部署时,永远不会触发onError方法。 (永远不会输出路由器开头的log语句)
在流应用程序的启动日志中,似乎正确地选择了bean并注册为errorChannel的侦听器,但是由于某些原因,当抛出异常时,它们不会在我们的onError方法中得到处理。路由器。
启动日志:
o.s.i.endpoint.EventDrivenConsumer : Adding {router:errorMessageMappingRouter.onError.router} as a subscriber to the 'errorChannel' channel
o.s.i.channel.PublishSubscribeChannel : Channel 'errorChannel' has 1 subscriber(s).
o.s.i.endpoint.EventDrivenConsumer : started errorMessageMappingRouter.onError.router
我们正在使用Spring Cloud Stream和kafka活页夹配置的所有默认设置:
spring.cloud:
stream:
binders:
kafka:
type: kafka
environment.spring.cloud.stream.kafka.binder.brokers=brokerlist
environment.spring.cloud.stream.kafka.binder.zkNodes=zklist
编辑:从kubectl describe <pod>
Args:
--spring.cloud.stream.bindings.input.group=delivery-stream
--spring.cloud.stream.bindings.output.producer.requiredGroups=delivery-stream
--spring.cloud.stream.bindings.output.destination=delivery-stream.enricher
--spring.cloud.stream.binders.xdkafka.environment.spring.cloud.stream.kafka.binder.zkNodes=<zkNodes>
--spring.cloud.stream.binders.xdkafka.type=kafka
--spring.cloud.stream.binders.xdkafka.defaultCandidate=true
--spring.cloud.stream.binders.xdkafka.environment.spring.cloud.stream.kafka.binder.brokers=<brokers>
--spring.cloud.stream.bindings.input.destination=delivery-stream.config-enricher
我们尝试过的另一个想法是尝试使用Spring Cloud Stream-Spring集成错误通道支持,以将有关错误的消息发送给代理主题,但是由于消息似乎根本没有降落在全局Spring Integration errorChannel中,那也不起作用。
在SCDF Kubernetes中需要做些特殊的事情来启用全局Spring Integration errorChannel吗?
我在这里想念什么?
使用评论中的解决方案进行更新:
查看完您的配置后,我现在可以确定我知道什么 问题是。您有一个多活页夹配置方案。即使 您只处理单个活页夹实例的存在 spring.cloud.stream.binders ....将要构成框架 将其视为多活页夹。基本上这是一个错误- github.com/spring-cloud/spring-cloud-stream/issues/1384。尽你所能 看到它已修复,但您需要升级到Elmhurst.SR2或抢 最新快照(我们在RC2和2.1.0中。发布已在几周之内 无论如何)– Oleg Zhurakousky
这确实是我们设置的问题。我们没有升级,而是暂时取消了多联机的使用,问题已解决。
答案 0 :(得分:0)
使用评论中的解决方案进行更新:
查看完您的配置后,我现在可以确定我知道什么 问题是。您有一个多活页夹配置方案。即使 您只处理单个活页夹实例的存在 spring.cloud.stream.binders ....将要构成框架 将其视为多活页夹。基本上这是一个错误- github.com/spring-cloud/spring-cloud-stream/issues/1384。尽你所能 看到它已修复,但您需要升级到Elmhurst.SR2或抢 最新快照(我们在RC2和2.1.0中。发布已在几周之内 无论如何)– Oleg Zhurakousky
这确实是我们设置的问题。我们没有升级,而是暂时取消了多联机的使用,问题已解决。