2017-11-11 147 views
0

在传统的微服务体系结构中,您可以在某些消息传递系统上发布相关的域事件,从而允许系统的其他部分作出反应。Lagom的远程持久化视图

现在想象一下,你有三个微服务:客户,订单和建议推荐微服务需要客户的信息订单提供其功能,例如将要从某些机器学习算法分析的所有客户和所有订单的列表。 现在,你需要有客户的状态上Recommandation微服务“加盟”订单:

  1. 你有Recommandation微服务听取客户和订单公布,并建立了自己的状态域中的事件。这会导致逻辑重复,因为您可能在客户和订单中已经具有相同的逻辑

  2. 在客户和订单的每个相关域消息中,您只需向他们询问特定客户或订单的状态。这很好,但是如果你有N个服务而不是仅仅需要建立一个物化视图的服务,你将会对客户和订单造成很大的负担

  3. 你让Customers和Orders自己发布“重量级”事件(不是域事件),它允许任何其他微服务在不处理域事件的情况下构建物化视图。这可以让你既a)不得复制逻辑B)不要不断地问同样的信息

有图案N.3一些缺陷,我们无法弄清楚,如果没有,你是如何实现它在Lagom?

回答

2

我会尽力解释一些信息,希望能给你更多的关于这个问题的看法,以及如何在Lagom中以可靠的方式实现它。

我们有几个概念,我们必须记住。其中最重要的是Event Sourcing本身。事件采购意味着系统中的任何国家都有其事件源。

我们要处理的第一个状态是持久实体状态。这个状态很重要,因为它与命令和事件处理程序一起定义了模型的一致性边界。

但系统中还有其他国家。事实上,我们可以创建尽可能多的,因为我们有Event Journal。阅读模式也是一种状态,也是由事件产生的。

有很多原因让你不应该将PersistentEntity的状态发布到其他系统。第一个是避免耦合的问题。你不希望你的数据泄露给其他服务。这就是有一个反腐败层(ACL)。

所以,从这里我们可以这样说:在发布订单和客户推荐服务之前,我会将其转换为OrderView和CustomerView(ACL 101)。

现在的问题是什么时候你会这样做?如果您在处理命令后尝试在卡夫卡发布它,则您不能保证该州将被发布。事件日志和Kafka主题之间没有XA事务。所以,有机会的话,该事件持续存在,但由于某些原因,国家没有公布卡夫卡。

如果你想要的数据走出以可靠的方式服务的,并不会产生业务之间的耦合,您有以下选择:

使用代理API和发布事件的话题。您不应按原样发布事件,而应将其转换为外部API(ACL)的格式。 使用读出侧处理器生成它的视图中,再次你希望使用的外部API格式。如果您愿意,可以将该ViewState发布到某个主题,以便其他服务可以直接使用该主题。

这就是说,有什么错在发布一个主题,是不是一个真正的事件中的东西,但一些派生的状态。问题是你如何保证它被有效地发布。这样做,从PersistentEntity里面是有风险的,因为你必须在-一次的语义。做这件事最可靠的方法是一个只读语法的读取过程。

进一步说明在线......

倾听来自客户和订单域事件,并在recommandation服务重建状态 。这是一个可怕的想法,因为你 将需要复制该处理在不同 界上下文

这不是一个可怕的想法事件的逻辑。这就是你如何让你的服务彼此独立。您需要实施以消耗事件的逻辑并不相同。正如你所说,这是一个不同的有限上下文,因为它只获得它所需要的。

泄漏从BC国家到另一个为我上述(反腐败层)的原因更成问题。

要实现脱钩,你确实需要更多的代码并没有什么不妥。在这一天结束时,构建微服务的原因是为了避免耦合,并且能够让服务发展和扩展而不会相互干扰。有一个价格可以支付,价格是编写更多的代码。你需要评估线索。

可以消耗自己的事件,产生订单查看CustomerView并发布到卡夫卡,但这是一样直接消耗事件的推荐服务。

请注意,您还需要在一些地方保存订单查看CustomerView的推荐服务。所以你最终要存储三次。在原始服务(查看表)上,在Kafka和推荐服务中。

这就是为什么在主题中发布事件是在服务之间传播数据的最佳选择。

我们收到来自客户或订单域事件时,都会去 他们,并要求他们的状态。这是可怕的,因为如果你有更多的 比一个微服务需要自己的状态,你最终会 生产客户负荷和订单

这的确是一个可怕的想法,因为你会推荐服务依赖于另外两项服务。如果订单或客户是向下,建议将普遍回落。这就是经纪人帮助解决的问题。

有客户和订单,不仅发布事件也是国家和 具有需要建立的所有服务物化视图听 他们所需要的状态如何申请与Lagom最后的模式?我们 发现没有办法听状态的变化,只是事件。一种解决方案 我们考虑暗示的出版与PubSub的状态在持久性实体的onEvent 处理程序,但我不知道这是正确的 的地方,做到这一点。

在onEvent处理程序中使用pubSub是所有的最差解决方案。原因有以下几点:

  1. PubSub的具有最多一次sematincs(见上述评论)

  2. 的事件处理程序调用多次。每当你重新水合物的实体,该事件被重播和事件处理程序将被用于这一点。这意味着你每次都会重新发布状态。实际上,你就解决了最多一次,PubSub的问题,但不是这样,你可能希望/欲望。

您可以使用afterPersist回调,但这并不可靠,因为pubSub最多只有一次。

PersistentEntity中的PubSub不应该用于您需要可靠的事情。这是一种尽力而为的能力,就是这样。