C# 使用数据库作为卡夫卡消息状态的存储是否正确?
目前,我已经实现了一个卡夫卡消费者,其工作原理如下: 在while循环中:C# 使用数据库作为卡夫卡消息状态的存储是否正确?,c#,.net-core,apache-kafka,confluent-platform,C#,.net Core,Apache Kafka,Confluent Platform,目前,我已经实现了一个卡夫卡消费者,其工作原理如下: 在while循环中: 消费卡夫卡的信息 将消耗的消息放入单独的任务中进行处理,这样主线程和使用者循环就不会被阻塞 2.1仅当处理成功或超出处理尝试次数时提交消息 步骤#2.1可能需要1秒到6小时才能完成 问题是,如果应用程序崩溃,并且有任务尚未完成,那么在应用程序重新启动时(甚至在重新平衡时),这些消息将被再次使用和处理 我不想自动提交偏移量,因为它最多只能保证一次交付。我正在考虑使用数据库作为消息状态的存储,并实现一个消费者,如下所示: 在
- 若数据库中存在消息且状态为“已完成”,则提交消息
- 如果数据库中存在消息,但状态为“进行中”,则直接转到步骤4
- 如果消息不存在,则转至步骤3
我不确定使用db是否是一种正确的方法,因为如果我有很多消息,它会减慢消费者的速度。您能给我一些建议,说明如何正确地实现consumer,使每条消息只处理一次吗?您的consumer应该从流(Kafka)中获取任务,以便流不再包含该任务。如果工作节点在运行任务时崩溃,则需要实施冗余/错误处理,即全局异常处理和持久临时存储。因此,我不建议将任务存储在流旁边的数据库中,但是如果要这样做,那么最好在Kafka中创建一个表,因为它们是持久的
当错误处理时,实现策略取决于您,因为有几种方法可以实现它,即如果节点崩溃,然后将任务重新准备到流中,准备由另一个节点捕获,或者您可以只记录任务并通知用户任务已失败。这是什么意思“您的消费者应该从流中获取任务(Kafka)”?在我的问题中,我说的是“将消耗的消息放入单独的任务中进行处理”,我指的是task.Run()我的意思是,当您开始使用消息时,不要将消息保存在kafka中,并将其状态更新为
进行中
,而是要完全使用消息,使其不再在消息队列中,然后任务的状态取决于其在管道中的位置。即,如果消息在kafka中,则消息已排队,如果消息在工作进程中,则任务的状态取决于消息在管道中的位置正在进行中,当进度完成时,您可以使用worker广播它已完成(这可能是它向用户发送通知等)。