简体   繁体   English

洋葱架构中的 Kafka 消费者

[英]Kafka Consumers in Onion Architecture

I am working with a project following DDD and has consumers to a Kafka Queue .我正在处理DDD之后的一个项目,并且有consumersKafka Queue My question is straight forward, where do the consumers reside in the Onion Architecture and Hexagonal Architecture ?我的问题是直截了当的, Onion ArchitectureHexagonal Architecture中的消费者住在哪里? Are they event handlers or should they be a part of the infrastructure?它们是事件处理程序还是应该成为基础设施的一部分?

I am using Kafka Consumers to listen to change events of other aggregate roots and want to store the data in my current aggregate .我正在使用Kafka Consumers来监听其他聚合根的更改事件,并希望将数据存储在我当前的aggregate中。 Basically replicating the data from one microservice to another.基本上将数据从一个微服务复制到另一个微服务。

The purpose of a (Kafka) consumer is very similar to the purpose of eg a RESTful endpoint - they both consume messages/requests from the outside world in order to convert them to something understandable by the Application . (Kafka)消费者的目的与例如 RESTful 端点的目的非常相似——它们都使用来自外部世界的消息/请求,以便将它们转换为应用程序可以理解的东西。 So, from Hexagonal Architecture point of view, a (Kafka) consumer is just an adapter .因此,从六角架构的角度来看,(Kafka)消费者只是一个适配器 Check also the drawing at page 148 from Microservices Patterns by Chris Richardson where a queue consumer (aka handler ) is placed as an adapter in the context of the Hexagonal Architecture .另请查看Chris Richardson 的 Microservices Patterns第 148 页的绘图,其中队列消费者(又名处理程序)作为适配器放置在Hexagonal Architecture的上下文中。

When thinking about Clean Architecture focus a bit on the mention about the flow control:在考虑清洁架构时,请注意提及流量控制:

It begins in the controller , moves through the use case, and then winds up executing in the presenter.从 controller 开始,遍历用例,然后在演示者中执行。

A (Kafka) consumer is the entry point for the outside messages, the flow control begins with it because there's nothing else to begin with and it basically behaves like a Controller ; (Kafka)消费者是外部消息的入口点,流控制从它开始,因为没有其他东西可以开始,它的行为基本上像Controller thus the (Kafka) consumer is part of Interface Adapters layer, Controllers section (see the image ).因此(Kafka)消费者是接口适配器控制器部分的一部分(见图)。

When considering Onion Architecture , I would compare the (Kafka) consumer to a Controller : both do the same thing, mainly receiving a request, despite the fact that the request's transport mechanism might differ.在考虑Onion Architecture时,我会将 (Kafka) 消费者与Controller进行比较:两者都做同样的事情,主要是接收请求,尽管请求的传输机制可能不同。 I consider that both should stay in the same place which is User Interface segment of the edge layer (notice the SpeakerController ).我认为两者都应该留在同一个地方,即边缘层用户界面部分(注意SpeakerController )。

About frameworks关于框架

Depending on the used framework, a message consumer might have nothing to directly do with external requests, instead it might directly receive some identifiers or even some domain object(s).根据使用的框架,消息使用者可能与外部请求没有直接关系,而是直接接收一些标识符甚至一些域对象。 Eg when using @KafkaListener from Spring for Apache Kafka the consumer could actually be an Use Case (Clean Architecture) or an Application Service (Onion Architecture);例如,当使用@KafkaListener中的@KafkaListener 用于 Apache Kafka时,消费者实际上可能是用例(清洁架构)或应用程序服务(洋葱架构); it could also be a domain service (Onion Architecture) and even an entity (very unlikely) when using some (Spring framework) tricks.当使用某些(Spring 框架)技巧时,它也可能是域服务(洋葱架构)甚至是实体(非常不可能)。

Conclusion结论

I think that the key to answer the post's question is to ask it this way: “is the consumer implementation depending on the infrastructure implementation?”.我认为回答帖子问题的关键是这样问:“消费者的实现是否取决于基础设施的实现?”。 If the answer is “yes” than one would at least know that the consumer implementation can't stay in the code/domain/model part of the application;如果答案是“是”,那么至少可以知道消费者实现不能停留在应用程序的代码/域/模型部分; if the answer is “no” (see “About frameworks” above) than the consumer implementation might be part of code/domain/model .如果答案是“否”(参见上面的“关于框架”),那么消费者实现可能是code/domain/model的一部分。

The way I see it is:我的看法是:

  1. Your aggregates are the Core您的聚合是核心

  2. The message handlers are Use Cases, which use dependencies (like repository interfaces) and the core to execute the business use case.消息处理程序是用例,它使用依赖项(如存储库接口)和核心来执行业务用例。

  3. There is infrastructure code that peeks messages from the queue and triggers use cases有基础设施代码可以从队列中窥视消息并触发用例

With this approach, you can unit test your use cases without worrying about infrastructure and you can replace the whole messaging queue technology.使用这种方法,您可以对用例进行单元测试,而无需担心基础设施,并且可以替换整个消息队列技术。 The same approach works for handling API requests.同样的方法适用于处理 API 请求。 In practice, the only difference is that with the API you can return a response synchronously, and with messaging you can't.在实践中,唯一的区别是使用 API 您可以同步返回响应,而使用消息传递则不能。

As a practical note, in .NET I use a library called Mediatr to implement and trigger the use cases.作为一个实用说明,在 .NET 中,我使用一个名为Mediatr的库来实现和触发用例。 In java, I found PipelinR which looks similar at first sight.在 java 中,我发现PipelinR 乍一看很相似。 This type of approach allows you to implement all use cases the same way for all your synchronous and asynchronous usages.这种方法允许您以相同的方式为所有同步和异步使用实现所有用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM