Kafka流异常处理

时间:2018-10-10 08:13:50

标签: apache-kafka apache-kafka-streams

我正在开发kafka-streams应用程序,但无法覆盖默认的ProductionExceptionHandler。
我创建了一个实现ProductionExceptionHandler的类

public class RtaCustomProcessingExceptionHandler implements ProductionExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(RtaCustomProcessingExceptionHandler.class);
    private RtaHandlerClient handlerClient;

    @Override
    public void configure(Map<String, ?> map) {
        handlerClient = RtaHandlerClient.getInstance();
    }

    @Override
    public ProductionExceptionHandlerResponse handle(final ProducerRecord<byte[], byte[]> record,
                                                     final Exception exception) {
        log.debug("PASSING");

        return ProductionExceptionHandlerResponse.CONTINUE;
    }
}

并将其添加到我的属性中

        properties.put(StreamsConfig.DEFAULT_PRODUCTION_EXCEPTION_HANDLER_CLASS_CONFIG,
            RtaCustomProcessingExceptionHandler.class);

我用来实例化KafkaStreams

this.streams = new KafkaStreams(BasicTopology.createTopology(config), config.asProperties());


当应用程序启动时,我可以在日志中看到我的处理程序正在被拾取

[2018-10-10 07:58:40,471] INFO StreamsConfig values: 
    application.id = xdr-0
    application.server = 
    bootstrap.servers = [kafka-1:9092]
    buffered.records.per.partition = 1000
    cache.max.bytes.buffering = 10485760
    client.id = 
    commit.interval.ms = 1000
    connections.max.idle.ms = 540000
    default.deserialization.exception.handler = class org.apache.kafka.streams.errors.LogAndFailExceptionHandler
    default.key.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde
    default.production.exception.handler = class com.ericsson.dcp.rtang.kafka.streams.xdr.error.handler.RtaCustomProcessingExceptionHandler
    default.timestamp.extractor = class org.apache.kafka.streams.processor.WallclockTimestampExtractor
    default.value.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde
    metadata.max.age.ms = 300000

但是随后在日志中似乎由于某种我无法理解的奇怪原因而被覆盖

 [2018-10-10 07:58:40,958] INFO StreamsConfig values: 
    application.id = xdr-0
    application.server = 
    bootstrap.servers = [kafka-1:9092]
    buffered.records.per.partition = 1000
    cache.max.bytes.buffering = 10485760
    client.id = xdr-0-99215001-f1fd-43ae-8c3f-026cbd11d013-StreamThread-1-consumer
    commit.interval.ms = 30000
    connections.max.idle.ms = 540000
    default.deserialization.exception.handler = class org.apache.kafka.streams.errors.LogAndFailExceptionHandler
    default.key.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde
    default.production.exception.handler = class org.apache.kafka.streams.errors.DefaultProductionExceptionHandler
    default.timestamp.extractor = class org.apache.kafka.streams.processor.FailOnInvalidTimestamp
    default.value.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde

有人知道为什么会这样吗?

BR
-Jiinxy

编辑:已根据请求更新了实际的处理程序实现。

EDIT2 :我已经设置了测试,因此我占用了10个要处理的项目,其中第6个项目包含一个值,该值通常会导致我自己的public class RtaRecoverableProcessingException extends ApiException但也{{1}据我所知,这两者都应由自定义处理程序捕获。 Ive还在第162(RecordTooLargeException和166(producer.send(..行的RecordCollectorImpl.java中添加了断点,我可以看到对于前五个项目,该过程正确地通过了第162和166行。可以理解,异常166行没有通过,因此我认为应该通过166行,即使抛出异常也是如此,因为它似乎是在191(if(exception..)行中处理的。

1 个答案:

答案 0 :(得分:2)

您的kafka流异常处理程序RtaCustomProcessingExceptionHandler是正确的,应该可以运行。 您可以通过将断点放在handle的方法ProductionExceptionHandler中进行测试,并模拟例外情况(例如,在处理消息期间抛出任何异常)。

即使在日志的第一部分中,您也会看到default.deserialization.exception.handler被应用。提供的日志的第二部分用于kafka流的内部需求,并且采用默认配置值(如果比较commit.interval.ms之类的其他属性,您还将看到所有属性都是默认属性)。