Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net core 当消费者运行时,在Confluent.Kafka中为主题使用消息_.net Core_Apache Kafka_Message Queue_Apache Zookeeper - Fatal编程技术网

.net core 当消费者运行时,在Confluent.Kafka中为主题使用消息

.net core 当消费者运行时,在Confluent.Kafka中为主题使用消息,.net-core,apache-kafka,message-queue,apache-zookeeper,.net Core,Apache Kafka,Message Queue,Apache Zookeeper,我在.netCore项目中使用Confluent.Kafka(1.4.4)作为消息代理。在项目启动时,我仅将“bootstrapserver”设置为appSetting.json文件中的特定服务器,并在必要时在API中生成消息,相关类中的代码如下: public async Task WriteMessage<T>(string topicName, T message) { using (var p = new ProducerBuilder<Null

我在.netCore项目中使用Confluent.Kafka(1.4.4)作为消息代理。在项目启动时,我仅将“bootstrapserver”设置为appSetting.json文件中的特定服务器,并在必要时在API中生成消息,相关类中的代码如下:

public async Task WriteMessage<T>(string topicName, T message)
    {
        using (var p = new ProducerBuilder<Null, string>(_producerConfig).Build())
        {
            try
            {
                var serializedMessage= JsonConvert.SerializeObject(message);
                var dr = await p.ProduceAsync(topicName, new Message<Null, string> { Value = serializedMessage });
                logger.LogInformation($"Delivered '{dr.Value}' to '{dr.TopicPartitionOffset}'");
            }
            catch (ProduceException<Null, string> e)
            {
                logger.LogInformation($"Delivery failed: {e.Error.Reason}");
            }
        }
    }
public异步任务WriteMessage(字符串topicName,T message)
{
使用(var p=new ProducerBuilder(\u producerConfig.Build())
{
尝试
{
var serializedMessage=JsonConvert.SerializeObject(消息);
var dr=await p.ProduceAsync(topicName,新消息{Value=serializedMessage});
logger.LogInformation($“已将“{dr.Value}”传递到“{dr.TopicPartitionOffset}”);
}
捕获(生产异常)
{
logger.LogInformation($“传递失败:{e.Error.Reason}”);
}
}
}
我还在消费者解决方案中添加了以下代码:

public async Task Run()
    {
        using (var consumerBuilder = new ConsumerBuilder<Ignore, string>(_consumerConfig).Build())
        {
            consumerBuilder.Subscribe(new List<string>() { "ActiveMemberCardForPanClubEvent", "CreatePanClubEvent", "RemovePanClubEvent"
            });

            CancellationTokenSource cts = new CancellationTokenSource();
            Console.CancelKeyPress += (_, e) =>
            {
                e.Cancel = true; // prevent the process from terminating.
                cts.Cancel();
            };

            try
            {
                while (true)
                {
                    try
                    {
                        var consumer = consumerBuilder.Consume(cts.Token);
                        if (consumer.Message != null)
                        {
                            using (LogContext.PushProperty("RequestId", Guid.NewGuid()))
                            {
                                //Do something
                                logger.LogInformation($"Consumed message '{consumer.Message.Value}' at: '{consumer.TopicPartitionOffset}'.");
                                await DoJob(consumer.Topic, consumer.Message.Value);
                                consumer.Topic.Remove(0, consumer.Topic.Length);
                            }

                        }
                        else
                        {
                            logger.LogInformation($"message is null for topic '{consumer.Topic}'and partition : '{consumer.TopicPartitionOffset}' .");
                            consumer.Topic.Remove(0, consumer.Topic.Length);
                        }
                    }
                    catch (ConsumeException e)
                    {

                        logger.LogInformation($"Error occurred: {e.Error.Reason}");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // Ensure the consumer leaves the group cleanly and final offsets are committed.
                consumerBuilder.Close();
            }
        }
    }
公共异步任务运行()
{
使用(var consumerBuilder=new consumerBuilder(\u consumerConfig.Build())
{
订阅(新列表(){“ActiveMemberCardForPanClubEvent”、“CreatePanClubEvent”、“RemovePanClubEvent”
});
CancellationTokenSource cts=新的CancellationTokenSource();
Console.CancelKeyPress+=(\uE)=>
{
e、 Cancel=true;//防止进程终止。
cts.Cancel();
};
尝试
{
while(true)
{
尝试
{
var consumer=consumerBuilder.consumer(cts.Token);
if(consumer.Message!=null)
{
使用(LogContext.PushProperty(“RequestId”,Guid.NewGuid()))
{
//做点什么
logger.LogInformation($“在:'{consumer.TopicPartitionOffset}'处使用的消息'{consumer.message.Value}'”;
等待DoJob(consumer.Topic、consumer.Message.Value);
consumer.Topic.Remove(0,consumer.Topic.Length);
}
}
其他的
{
logger.LogInformation($“主题“{consumer.topic}”和分区“{consumer.TopicPartitionOffset}”的消息为空”;
consumer.Topic.Remove(0,consumer.Topic.Length);
}
}
捕获(消费异常)
{
logger.LogInformation($”发生错误:{e.Error.Reason}”);
}
}
}
捕获(操作取消异常)
{
//确保消费者干净地离开集团,并提交最终补偿。
consumerBuilder.Close();
}
}
}
我生成了一条消息,当消费者项目运行时,一切都很顺利,消息正在消费者解决方案中读取。 当consumer项目未运行,并且我将API中的消息与API中的消息生成器一起排队时,就会出现问题。在运行consumers之后,没有任何关于该主题的有效消息生成它的消息。
我熟悉并有消息代理的经验,我知道通过发送消息,它将一直在总线上,直到被使用为止,但我不明白为什么它在这个项目中不能与Kafka一起工作。

消费者属性“auto.offset.reset”的默认设置是“最新的”

这意味着(在尚未写入偏移量的情况下),如果您向某个主题写入消息,然后启动使用者,则它将跳过在使用者启动之前写入的任何消息。这可能就是为什么您的消费者看不到生产者排队的消息

解决方案是将“auto.offset.reset”设置为“最早”,这意味着消费者将从主题的最早偏移开始


Kafka主题有基于时间或字节大小的清理策略。默认保留时间为7天。直到消息被消费一次,它才删除消息。请检查与“保留”相关的主题配置。那么,为什么在运行consumer之后,为主题生成的消息为空?对不起,我可能误解了您的句子“在运行consumers之后,没有为该主题生成任何有效消息,即该主题的消息正在生成。”你能试着重新措辞或显示一些示例消息吗?问题解决了勾选的答案是我问题的解决方案确切地说,它对我很好,问题解决了。感谢您的回答,如果您能再次肯定我的问题,我将不胜感激。谢谢您的回答,但在解决了上一个问题后,我仍然有另一个问题。我注意到,每当我重新启动消费者项目时,上一个会话中使用的消息仍然有效,并且正在重复使用用过。你知道这个问题吗?一旦你成功地处理了一条消息,你就可以“提交”它的偏移量。您的消费者API可能有某种提交方法可以用来实现这一点。下面是java方法