Apache kafka 没有消息时从卡夫卡消费者处返回

Apache kafka 没有消息时从卡夫卡消费者处返回,apache-kafka,kafka-consumer-api,librdkafka,Apache Kafka,Kafka Consumer Api,Librdkafka,我想使用处理应用程序启动中的主题。假设以下示例: while (true) { try { var cr = c.Consume(); Console.WriteLine($"Consumed message '{cr.Value}' at: '{cr.TopicPartitionOffset}'."); } catch (ConsumeException e)

我想使用处理应用程序启动中的主题。假设以下示例:

    while (true)
    {
        try
        {
            var cr = c.Consume();
            Console.WriteLine($"Consumed message '{cr.Value}' at: '{cr.TopicPartitionOffset}'.");
        }
        catch (ConsumeException e)
        {
            Console.WriteLine($"Error occured: {e.Error.Reason}");
        }
    }
当卡夫卡中没有新消息时,c.Consume将被阻止。因为我想用它来启动应用程序,比如缓存预热,所以当我发现没有新消息时,我想继续我的代码


我知道像c.Consumetimeout这样的设置超时有一个重载,但是这种方法的问题是,如果您的主题中有一条消息,并且读取消息的持续时间超过了您的超时时间,那么您将收到空输出,这是不可取的

消费者不应该意识到生产者

现在,如果您想知道您从开始消费的那一刻起就已经阅读了本主题的所有内容,您可以:

在开始使用之前加载最新的偏移量。 然后开始使用消息。 如果邮件的偏移量与之前加载的最新偏移量相同,请停止使用。 我不是一个C开发人员,但根据我在dotnet confluent文档中读到的内容,你可以将QueryWaterMarkOffset称为消费者,以获取最旧和最新的偏移量

然后,在Messageclass上有一个偏移量访问器。因此,整个事情不应该太难实现。

您可以使用OnPartitionEOF事件来指示您已到达分区的末尾

CancellationTokenSource source = new CancellationTokenSource();
bool isContinue = true;

c.OnPartitionEOF += (o, e) =>
    {
        Console.WriteLine($"You have reached end of partition");
        isContinue = false;
        source.Cancel();
    };    
while (isContinue)
{
    try
    {
        var cr = c.Consume(source.Token);
        Console.WriteLine($"Consumed message '{cr.Value}' at: '{cr.TopicPartitionOffset}'.");
    }
    catch (ConsumeException e)
    {
        Console.WriteLine($"Error occured: {e.Error.Reason}");
    }
}

我发现Consumer.IsPartitionEOF很有用。

那么您想要停止消费的方法是什么呢?是否有一种方法表明我们已经到了分区的末尾?谢谢。但OnPartitionEOF已按照您的欢迎中所述删除。所以,您可以在消费后通过检查cr.IsPartitionEOF来检测分区结束。IsPartitionEOF应该可以工作,但我不知道为什么它总是返回false,我只是用一条消息创建了一个主题。此外,我必须等待可能被阻止的第一个消费呼叫,以检查IsPartitionEOF。也许稳定版本解决了这个问题,我没有工作是因为我没有在config中启用它:var config=new ConsumerConfig{EnablePartitionEof=true};您能否更改您的答案以反映iPartitionEOF功能,以便其他用户可以使用它?谢谢。这给了我末端偏移量,效果很好!你能把QueryWatermarkOffsets方法添加到你的答案中吗?我通过以下查询接收水印:var watermark=c.QueryWatermarkOffsetsnew-TopicPartitionmytopic,new-Partition0,TimeSpan.frommillistes1;嗨,我已经更新了我的答案,提到了QueryWatermarkOffsets而不是GetWatermarkOffsets。很高兴这对你有帮助。请试着对答案做出适当的解释。