比方说,我有topicA,topicB和topicC,这两个主题均基于域实体按不同的事件类型进行隔离。 topicA仅与eventA一起使用,topicB保留eventB,topicC仅与eventC一起使用。所有事件均按业务领域相互关联,但由单独的微服务产生,应按特定顺序进行处理。
问题是,如何使用Apache Kafka按特定顺序引入消耗事件,eventA然后等待接收eventB,然后当eventC接收时消耗所有事件。
感谢任何反馈,欢迎提出任何疑问。
一些注意事项: Kafka Streams是一种很好的方法,但是受公司政策的限制。
此外,我浏览了Join Pattern,但没有找到任何可靠的实现方法。
答案 0 :(得分:2)
如果事件相互关联,则应转到一个主题。因此,微服务1应该使用(键,值)和标签(事件A)推送事件A。同样,microservice-2和microservice-3应该将数据推送到一个通用主题。
这将在消费者方面为您提供帮助。
答案 1 :(得分:2)
可能有很多方法可以解决此问题。这是我可以建议的几个:
引入相关性ID ,它将链接来自主题A,B和C的事件。然后,按以下方式使用相关性ID:
服务A,B和C产生与相应主题相关的事件,但相关事件具有相同的相关ID
服务D使用来自不同主题的事件。每当服务D接收到来自任何主题的事件时,服务D要么通过相关ID将事件数据插入数据库,要么在接收到所有数据时执行某些操作。
例如,当服务D接收到事件C时,它首先发出查询以检查数据库中是否有来自事件C的具有关联ID的记录:
对于每个消耗的事件,依此类推。
产生事件的链服务 (A,B和C)。例如,可以按以下方式形成链:
服务A对主题A产生事件
服务B使用主题A中的事件,并向主题B中生成事件(可能是将事件A和B聚合在一起)
服务C使用主题B中的事件,并向主题C中生成事件(可能是将事件A,B和C聚合在一起)
最后,服务D使用主题C的事件(可能与A,B和C聚合)并执行所需的操作。
这种方法的变化(在每个中间阶段不汇总事件)将是链接服务并侦听链中的最后一个事件。当消耗了最后一个事件时,请向相应的主题发出Kafka pull,以获取其他服务产生的事件。
答案 2 :(得分:1)
由于您要询问有关在不同主题之间对消息的消费进行排序的问题,因此第一种选择是让一个消费者产生一条消息,为下一个消费者提供食物(这些消费者可能会或可能不在同一过程中):
消费者A处理消息->消费者A将新消息放在不同的主题上->消费者B拾取新消息并进行处理->消费者B将新消息放在第二个主题上->等等...等等。
如果Stream实际上是在后台进行此操作或进行类似的处理,我不会感到惊讶。可以使用任何其他类型的进程间通信接口:RDP,内存映射文件,互斥锁,管道;选择。
除非万不得已,否则我将尽量避免在同一主题上放置不同的事件。当您将多个事件放在单个队列/主题上时,会以几种方式限制消费者:
一个现实的例子是在游乐园中。假设您有两种类型的游乐园访客:快速通过和标准顾客。您的业务规则规定,“快速通过”客户可以跳过标准客户之前的排队。
如果将它们合并到一个队列/主题中,该怎么做?答案是优先级排队。您问所有排队的人是否都通过快速通行,这容易出错并且效率低下(这是优先级排队;可以工作,但可能不是最佳解决方案)。大多数游乐园通过设置两个单独的队列(每种类型的客户[事件/消息]一个)来解决此问题。现在,他们可以将客户送入两个单独的服务员中(一个FastPass一个Standard),或者他们可以让一个服务员同时执行两个队列,首先清空快速通过队列。
最终,这取决于您的约束:一天是10条消息,还是10亿条,您需要即时一致性还是最终一致性?是在IoT设备上吗?