我正在使用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有类似的属性(我找不到)?请帮忙。
答案 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专家,请告诉我是否有任何后果,因为我没有找到任何。