在 CQRS 工作流中获取另一个域的数据的推荐方法是什么?

What is the recommended way to get another domain's data in a CQRS workflow?

我正在研究具有分离数据库的微服务架构,但需要复制一些数据以实现弹性。

举个例子,假设我正在写一个博客并且有两个域:usersarticles,每个域都有自己的数据库。如果 users 微服务出现故障,我仍然需要能够显示文章作者姓名。

-- in the 'users' domain's database

create table users (
  id uuid primary key,
  name varchar(32)
);
-- in to the 'articles' domain's database

create table articles (
  id uuid primary key,
  author uuid,
  author_name varchar(32),
  contents text
);

因此,当我创建文章时,我会发送用户标识符。

我的问题是,我应该在什么时候以及如何获得用户名?

  1. 我不相信用户会发送真实的用户名,它必须从系统的某个地方获取
  2. 我无法从控制器获取它,因为它在另一个域上
  3. 我无法从事件处理程序中获取它,因为它在另一个域上
  4. 我不能使用 saga,因为 saga 不应该进行查询,只能进行命令

FWIW,我对这些的参考是 this F.A.Q

非常感谢您阅读本文;我希望你能为我提供解决方案!祝你有个愉快的一天。

My question is, at what point and how am I supposed to get the username?

1) 你从引用数据的本地缓存中获取用户名 2)您的报告逻辑需要支持缓存还没有参考数据副本的情况 3) 您的报告逻辑需要支持引用数据的缓存副本过时的情况。

这里的参考数据是 shorthand 服务需要的任何信息,它本身不是授权机构。

因此,在典型的解决方案中,用户服务将拥有用户名的权威 copy/copies,以及用于确定是否允许更改该值的所有逻辑。文章服务将拥有该数据的本地副本,以及描述该信息可以使用多长时间的元数据。

用户数据库将拥有它负责的所有信息的副本。文章数据库将只有文章服务关心的那部分用户信息。

一种常见的实现方式是安排订阅,当非权威副本不再新鲜时,将数据从用户数据库拉到文章数据库。

您可以将缓存视为后备位置——如果我们无法及时访问最新的用户名,则使用缓存的副本。

但没有魔法 - 有时会发生远程数据不可用且本地缓存没有有效副本的情况。

请记住,您的许多数据已经是参考数据——由现实世界复制到您的本地数据库中。

If I may ask, instead of having metadata then pulling the data periodically to update the cache, shouldn't I just replicate it once then listen for the 'username changed' event?

如果该活动没有送达会怎样?

在分布式系统中,询问如果某些进程失败或某些消息在关键点丢失时会发生什么是非常重要的。你恢复的怎么样了。

当我沿着这条思路走下去时,我最终得出的结论是,客户端轮询是检索参考数据的主要机制,而推送通知是 延迟优化,表明我们应该现在轮询,而不是等待整个预定的时间间隔。