Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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
C# 使用数据库作为卡夫卡消息状态的存储是否正确?_C#_.net Core_Apache Kafka_Confluent Platform - Fatal编程技术网

C# 使用数据库作为卡夫卡消息状态的存储是否正确?

C# 使用数据库作为卡夫卡消息状态的存储是否正确?,c#,.net-core,apache-kafka,confluent-platform,C#,.net Core,Apache Kafka,Confluent Platform,目前,我已经实现了一个卡夫卡消费者,其工作原理如下: 在while循环中: 消费卡夫卡的信息 将消耗的消息放入单独的任务中进行处理,这样主线程和使用者循环就不会被阻塞 2.1仅当处理成功或超出处理尝试次数时提交消息 步骤#2.1可能需要1秒到6小时才能完成 问题是,如果应用程序崩溃,并且有任务尚未完成,那么在应用程序重新启动时(甚至在重新平衡时),这些消息将被再次使用和处理 我不想自动提交偏移量,因为它最多只能保证一次交付。我正在考虑使用数据库作为消息状态的存储,并实现一个消费者,如下所示: 在

目前,我已经实现了一个卡夫卡消费者,其工作原理如下:

在while循环中:

  • 消费卡夫卡的信息
  • 将消耗的消息放入单独的任务中进行处理,这样主线程和使用者循环就不会被阻塞 2.1仅当处理成功或超出处理尝试次数时提交消息
  • 步骤#2.1可能需要1秒到6小时才能完成

    问题是,如果应用程序崩溃,并且有任务尚未完成,那么在应用程序重新启动时(甚至在重新平衡时),这些消息将被再次使用和处理

    我不想自动提交偏移量,因为它最多只能保证一次交付。我正在考虑使用数据库作为消息状态的存储,并实现一个消费者,如下所示:

    在while循环中:

  • 消费卡夫卡的信息
  • 检查数据库是否存在此类消息
    • 若数据库中存在消息且状态为“已完成”,则提交消息

    • 如果数据库中存在消息,但状态为“进行中”,则直接转到步骤4

    • 如果消息不存在,则转至步骤3

  • 将状态为“正在进行”的消息保存到数据库中
  • 将消耗的消息放入单独的任务中进行处理,这样主线程和使用者循环就不会被阻塞 4.1只有在处理成功或超过处理尝试次数时,才提交消息并将数据库中的状态更改为“已完成”

  • 我不确定使用db是否是一种正确的方法,因为如果我有很多消息,它会减慢消费者的速度。您能给我一些建议,说明如何正确地实现consumer,使每条消息只处理一次吗?

    您的consumer应该从流(Kafka)中获取任务,以便流不再包含该任务。如果工作节点在运行任务时崩溃,则需要实施冗余/错误处理,即全局异常处理和持久临时存储。因此,我不建议将任务存储在流旁边的数据库中,但是如果要这样做,那么最好在Kafka中创建一个表,因为它们是持久的


    当错误处理时,实现策略取决于您,因为有几种方法可以实现它,即如果节点崩溃,然后将任务重新准备到流中,准备由另一个节点捕获,或者您可以只记录任务并通知用户任务已失败。

    这是什么意思“您的消费者应该从流中获取任务(Kafka)”?在我的问题中,我说的是“将消耗的消息放入单独的任务中进行处理”,我指的是task.Run()我的意思是,当您开始使用消息时,不要将消息保存在kafka中,并将其状态更新为
    进行中
    ,而是要完全使用消息,使其不再在消息队列中,然后任务的状态取决于其在管道中的位置。即,如果消息在kafka中,则消息已排队,如果消息在工作进程中,则任务的状态取决于消息在管道中的位置正在进行中,当进度完成时,您可以使用worker广播它已完成(这可能是它向用户发送通知等)。