微服务创建实体实现

Microservices Create Entity Implementation

这是我概述的问题的后续问题

网关作为应用程序的入口点,来自客户端的每个请求都指向该应用程序。然后网关将请求分配给负责的微服务并处理身份验证。

在这种情况下,网关监听 HTTP POST /bok 并通知 Microservice A 创建一本书。因此 Microservice A 负责管理和存储有关图书实体的所有内容。


以下伪代码是该架构的简化实现:

队列通信

网关

router.post('/book', (req, res) => {
  queue.publish('CreateBook', req.body);
  queue.consume('BookCreated', (book) => {
    const user = getUserFromOtherMicroService(book.userId);
    res.json({ book, user });
  });
});

微服务 A

queue.consume('CreateBook', (payload) => {
  const book = createBook(payload);
  eventStore.insert('BookCreated', book);
  const createdBook = updateProjectionDatabase(book);
  queue.publish('BookCreated', createdBook);
})

但我不太确定,原因如下:

  1. 每次用户请求创建新书时,将重新创建 Gateway 中用于使用 BookCreated 的侦听器
  2. 如果 2 个用户同时创建一本书并且 return 编辑了错误的书怎么办?
  3. 我不知道如何获取额外的数据(例如 getUserFromOtherMicroService

这就是我考虑实施此架构的原因:

直接和队列通信

网关

router.post('/book', async (req, res) => {
  const book = await makeHttpRequest('microservice-a/create-book', req.body);
  const user = await makeHttpRequest('microservice-b/getUser', book.userId);
  res.json({ book, user });
});

微服务 A

router.post('/create-book', (req, res) => {
  const book = createBook(req.body);
  eventStore.insert('BookCreated', book);
  const createdBook = updateProjectionDatabase(book);
  queue.publish('BookCreated', createdBook);
  res.json(createdBook);
})

但我也不太确定这个实现,因为:

  1. 我return创建后的书不是违反了CQRS吗? (因为我应该只 return OKERROR
  2. 在微服务系统中再发起一个HTTP请求不是很低效吗?

基于以上评论。

方法一

在这种情况下,您的 api 网关将用于丢弃队列中的邮件。如果您的流程需要很长时间并且您有一个队列工作人员坐在后面接收消息和流程,则此方法更合适。但是您的客户端必须进行轮询才能获得结果。假设您正在寻找机票。你放下消息。你得到一个 ID 来投票。您的客户将继续进行投票,直到结果可用。

但在这种情况下,您将遇到一个挑战,因为您丢弃了消息,您将如何生成客户端将轮询的 ID?您是否将 ID 分配给网关处的消息并放入队列中,并 return 相同的 ID 供客户端轮询以获得结果?同样,这种方法适用于 web/worker 种情况。

方法二

因为您的 API 网关是自定义应用程序,可以处理身份验证并将请求重定向到相应的服务。您的 Microsvc A 将创建书籍并发布事件,而您的微服务 B 和 C 将使用它。您的网关将等待微服务 A 对 return 的响应,其中包含所创建书籍的 ID(或新创建对象的事件元数据),这样您以后就不会轮询它,客户端就会拥有它。如果您愿意,您可以从此时可以获取的其他微服务获得更多信息,并可以发送聚合响应。

对于微服务 A、B、C 中可用的任何数据,您将通过网关获取。确保您的网关具有高可用性。

希望对您有所帮助。如果您有任何问题,请告诉我!