确保消息的有序处理

时间:2019-06-25 15:02:00

标签: java spring-boot apache-kafka microservices

因此,在微服务架构中,我需要保证将处理具有公共标识符的传入消息,以便它们来自kafka:

      message2, message1 kafka
     ------------------------------
             |message1       |message2
             |               |
         Instace1         Instance2

在下面的示例中,我有两个服务实例正在处理来自kafka的消息,但我想确保仅在message2之后才处理message1

显然,可以通过将一个实例配置为仅从特定分区进行消费来轻松解决这种情况,该特定分区将存储带有公用标识符的消息:

message2, message1 kafka
--------------------------------
       | message2
       | message1
     Instance1        Instance2

现在可以保证订单有效,并且message2永远不会在message1之前得到处理。

但是,我想知道是否可以通过其他方式直接在代码中而不是依赖于基础结构来解决此问题?看起来这可能是微服务体系结构中的一个标准问题,但是我不确定解决该问题的首选方法是什么?

3 个答案:

答案 0 :(得分:1)

Kafka仅保证订购within a partition

因此,如果要在“ message2”之前处理“ message1”,则需要确保两条消息都位于同一分区上。这样一来,保证所有阅读这些消息的消费者都能按产生的顺序看到它们。

答案 1 :(得分:1)

我建议将基础结构作为更“正确”的方法,但是应该可以通过代码解决此问题:

如果您只有一个消息生成者,请在消息上附加直接消息的标识符,在使用消息之前,请确保您之前已经使用了直接消息的消息。

如果您有多个生产者,这将变得有些棘手,因为您必须同步标识符。

同样,我建议基础架构是解决此问题的“更正确”的方式(编写的代码越少,复杂程度越小,您将拥有的错误越少)。

答案 2 :(得分:0)

您可以禁用自动提交功能,并提交您手动使用的消息的偏移量。 查看this链接以了解如何配置它。 然后,通过具有保存消息的最后使用索引的变量,您可以执行所需的操作,但是必须确保一个代码实例一次可以访问此变量。您可以使用其他微服务通过信号量来存储/保护此值。

因此,每个使用者等待直到当前消息之前的所有消息都被消耗掉,然后开始消耗消息以保存消息顺序。

但是这种解决方案增加了代码的复杂性,在这种情况下使用多个消费者的好处是什么?在最佳情况下,如果要保存订单或消息,则在性能方面,使用1个使用方或10个使用方不会有任何区别,因为使用方必须等到以前的消息出现错误为止。