0

我正在使用 Kafka 来解耦我的服务,但我对服务消费和产生输入和输出的方式有一些想法。

如果我有一个服务 A,它从我无法控制的某个外部服务中获取数据,我将被迫适应外部系统提供的数据格式(域)。按照这种做法,我的服务 A 将其结果以自己的格式(域)推送到主题。

顺便说一句,我有一个服务 B,它与服务 A 做类似的事情,但使用其他一些外部服务,并且有自己的数据格式(域),它推送到一个单独的主题。

现在,A 和 B 产生的数据的语义相似,但又不一样。但是,管道中的下一步是服务 C,它应该消耗 A 和 B 产生的东西,用它做一些事情并吐出结果。

C 是否应该只知道如何从一个地方使用数据,这意味着 A 和 B(以及未来的任何其他)需要在 C 特定域中产生它们的输出?这意味着,如果 C 消费者改变了它的域,A、B 和任何其他生产者都必须改变,我不喜欢这样。另外,如果我添加另一个消费者 D,例如,这意味着 A 和 B,使用这个类比,应该知道 D 也是他们的消费者,这对我来说看起来很可怕。

我在想 C 应该对它的输入负责,这意味着它依赖于 A 和 B 模型(以及任何其他可能产生自己数据的模型)。这也意味着,当添加新源时,必须更改 C 以包含该数据。

实际上,我倾向于使用 ManySources-OneSink 组件,而不是 OneSource-ManySinks。

有没有首选的做法?

4

4 回答 4

4

您在谈论的是上下文映射。BC 之间的关系。上游和下游两侧。在两个 BC 之间的关系中,您不能选择决定两者中的哪一个是上游和下游。它们本身就是。您可以选择如何集成(使用 REST API、使用事件、同步、异步……)。您应该绘制一个上下文图,确定哪种战略模式适用于 BC 之间的每种关系,并决定如何实施它。

于 2018-10-09T05:43:15.377 回答
2

在选择集成模式之前,需要在战略层面上对业务子域、将维护这些服务的团队、谁拥有什么、您期望模型如何发展等进行分析。

我建议看一下DDD 书中的上下文映射部分,然后看一下 Hohpe 和 Woolf 的Enterprise Integration Patterns以了解具体实现。

于 2018-10-08T08:54:41.547 回答
1

有没有首选的做法?

消息规范。

也就是说,您可以将它们转换为消息格式 mA、mB 和 mC,而不是将 A、B 和 C 相互耦合。只要 (mA, mB, mC) 兼容,服务就可以相互通信。

实现这一点的一种方法是将 mA、mB 和 mC 限制为同一模式的不同“版本”,其中模式的演变受到限制

  • 初始版本后不得添加新的必填字段
  • 可选字段应具有默认值
  • 消费者应忽略无法识别的字段
  • 字段可以被弃用,但它们永远不会被重复使用(例如,请参阅HTTP 状态代码 306

Greg Young 的书《事件源系统中的版本控制》专门用一章介绍了这个想法。如果您查看各种标准化的消息序列化(Avro、Protocol Buffers 等),您会看到类似的想法。

一项服务是否应该根据自己的主题产生输出并让依赖服务从中消费,反之亦然,还是第三种选择?

大多数情况下,这是管道——我们如何将消息从一个系统复制到另一个系统?

从概念上讲,您似乎希望 C 使用 A 和 B 生成的消息的逻辑外连接。所以我想最直接的问题是,您当前是否有来自 A 的这些相同消息的消费者不想要这些消息来自 B,反之亦然。如果这是您知道的唯一用例,那么将事情减少到一个主题可能会有好处。

于 2018-10-08T13:35:05.193 回答
0

您的每个服务都应使用对其特定业务逻辑最有意义的数据格式。

出于集成目的:

  • Inbound channel adapters- 在数据进入服务时将其转换为所需的格式。
  • Outbound channel adapters- 在退出服务时将数据转换为期望的格式。

欲了解更多信息: https ://www.enterpriseintegrationpatterns.com/patterns/messaging/ChannelAdapter.html

于 2018-10-05T11:04:08.083 回答