【发布时间】:2018-03-19 10:10:23
【问题描述】:
我使用的消费者组只有一个消费者,只有一个经纪人(docker wurstmeister image)。在代码中决定是否提交偏移量 - 如果代码返回错误,则不提交消息。我需要确保系统不会丢失任何消息——即使这意味着永远重试相同的消息(现在;))。为了测试这一点,我创建了简单的处理程序,它不会在“错误”字符串作为消息发送到 kafka 的情况下提交偏移量。所有其他字符串都已提交。
kafka-console-producer --broker-list localhost:9092 --topic test
>this will be commited
正在运行
kafka-run-class kafka.admin.ConsumerGroupCommand --bootstrap-server localhost:9092 --group michalgrupa --describe
返回
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
test 0 13 13 0
没关系,没有滞后。现在我们传递 'error' 字符串来假装发生了不好的事情并且没有提交消息:
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
test 0 13 14 1
当前偏移量保持在正确位置 + 有 1 条滞后消息。现在,如果我们再次传递正确的消息,偏移量将移动到 15:
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
test 0 15 15
并且第 14 号消息将不会再被拾取。这是默认行为吗?我是否需要手动跟踪最后一个偏移量并通过 it+1 加载消息?我已将提交间隔设置为 0,希望不使用任何 auto.commit 机制。
获取/提交代码:
go func() {
for {
ctx := context.Background()
m, err := mr.brokerReader.FetchMessage(ctx)
if err != nil {
break
}
if err := msgFunc(m); err != nil {
log.Errorf("# messaging # cannot commit a message: %v", err)
continue
}
// commit message if no error
if err := mr.brokerReader.CommitMessages(ctx, m); err != nil {
// should we do something else to just logging not committed message?
log.Errorf("cannot commit message [%s] %v/%v: %s = %s; with error: %v", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value), err)
}
}
}()
阅读器配置:
kafkaReader := kafka.NewReader(kafka.ReaderConfig{
Brokers: brokers,
GroupID: groupID,
Topic: topic,
CommitInterval: 0,
MinBytes: 10e3,
MaxBytes: 10e6,
})
【问题讨论】:
标签: go apache-kafka