在camel-kafka中抛出异常时不要提交偏移量

时间:2017-05-02 11:17:02

标签: java apache-camel apache-kafka kafka-consumer-api

我正在使用camel-kafka组件。我们必须遵循严格的订单,我们不能承受消息丢失。因此,在某些异常的情况下,我们不想提交偏移量。我设置了 autoCommitEnable = false 而没有处理异常。但是无论抛出哪个异常,都会提交偏移量(仅打印堆栈跟踪。)

为了处理这个场景,我更改了camel-kafka中的源代码。这是片段:

 try {
        KafkaConsumer.this.processor.process(exchange);
        if (KafkaConsumer.this.endpoint.getConfiguration().isAutoCommitEnable() != null
                && !KafkaConsumer.this.endpoint.getConfiguration().isAutoCommitEnable()
                        .booleanValue()) {
            this.consumer.commitSync(Collections.singletonMap(partition,
                    new OffsetAndMetadata(record.offset() + 1L)));
// Commit one by one
        }
    } catch (Exception arg13) {
        KafkaConsumer.this.getExceptionHandler().handleException("Error during processing",
                exchange, arg13);
        if (KafkaConsumer.LOG.isTraceEnabled()) {
            KafkaConsumer.LOG.trace(
                    "Caught an exception while processing partition {}, Kafka message (offset = {}) ",
                    Integer.valueOf(record.partition()), Long.valueOf(record.offset()));
        }
        break; // Break in case of any exception 
    }

但这里也没有运气。即使我写了处理程序,流程也不会出现在Catch块中。因此抵消总是得到承诺。这是正常的行为吗?如果出现异常,如何阻止camel提交偏移?

我可以看到spring-kakfa " ackOnError" 中有属性。我们在camel-kafka有类似的属性(我找不到)?请帮忙。

1 个答案:

答案 0 :(得分:0)

最后,经过大量调试后,我可以看到camel没有传回异常,并将其作为属性“Exchange.EXCEPTION_CAUGHT”进行交换。所以这里是我通过改变camel-kafka的KafkaConsumer.java#run类来编写的示例代码,以便在异常情况下不提交偏移量。

try {
      KafkaConsumer.this.processor.process(exchange);
      Throwable e1 = (Throwable) exchange.getProperty(Exchange.EXCEPTION_CAUGHT , Throwable.class);
        if (e1 != null) {
                throw e1;
            }
            if (KafkaConsumer.this.endpoint.getConfiguration().isAutoCommitEnable() != null
                                        && !KafkaConsumer.this.endpoint.getConfiguration().isAutoCommitEnable()
                                                .booleanValue()) {
            this.consumer.commitSync(Collections.singletonMap(partition,
                                            new OffsetAndMetadata(record.offset() + 1L)));
            }
            } 
            catch (Throwable arg13) {
                KafkaConsumer.this.getExceptionHandler().handleException("Error during processing",
                                        exchange, arg13);
                    break;
            }

到目前为止,这个例子为我工作并且工作正常。如果有人是Camel或Kafka专家,请告诉我是否有任何后果,因为我没有找到任何。