微服务创建实体实现 [英] Microservices Create Entity Implementation

查看:26
本文介绍了微服务创建实体实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在

网关

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 个用户同时创建一本书并且返回错误的书怎么办?
  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. 我在创作后归还图书时是否违反了 CQRS?(因为我应该只返回 OKERROR)
  2. 在微服务系统中发出另一个 HTTP 请求是不是效率低下?

解决方案

基于以上评论.

方法一

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

但在这种情况下,您将面临一个挑战,当您删除消息时,您将如何生成客户端将轮询的 ID?您是否将 ID 分配给网关处的消息并放入队列并返回相同的 ID 以供客户端轮询以获取结果?这种方法再次适用于网络/工人类型的场景.

方法二

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

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

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

This is a follow-up question to my issue outlined here.

The Gateway serves as an entry point to the application, to which every request from the client is made. The gateway then allocates the request to the responsible microservices and also handles authentication.

In this case the gateway listens for HTTP POST /bok and notifies the Microservice A to create a book. Thus Microservice A ist responsible for managing and storing everything about the book entity.


The following pseudo-code is a simplified implementation of this architecture:

Queue Communication

Gateway

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

Microservcie A

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

But I am not quite sure about this because of the following reasons:

  1. The listener for consuming BookCreated in the Gateway will be recreated every time a user requests to create a new book
  2. What if 2 users simultaneously create a book and the wrong book will be returned?
  3. I don't know how to fetch additional data (e.g. getUserFromOtherMicroService)


That's why I though about implementing this architecture:

Direct and Queue Communication

Gateway

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 });
});

Microservice 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);
})

But I am also not really sure about this implementation because:

  1. Don't I violate CQRS when I return the book after creation? (because I should only return OK or ERROR)
  2. Isn't it inefficient to make another HTTP request in a microservices system?

解决方案

Based on the comments above .

Approach 1

In this case your api gateway will be used to drop the message in the queue. This approach is more appropriate if your process is going to take long time and you have a queue workers sitting behind to pick up the messages and process. But your client side has to poll to get the results. Say you are looking for airline ticket . You drop the message. Your get an ID to poll. Your client will keep on polling until the results are available.

But in this case you will have a challenge , as you drop the message how you are going to generate the ID that client would poll ? Do you assign the ID to message at Gateway and drop in the queue and return the same ID for the client to poll to get result ? again this approach is good for web/worker kind of scenario.

Approach 2

Since Your API gateway is custom application that would handle the authentication and redirect the request to respective service. Your Microsvc A would create book and publish the event and your Microservice B and C would be using it . Your Gateway will wait for the Microservice A to return response with ID (or event metadata of newly created object) of book that is created so you don't poll for it later and client has it. If you want you can have additional information from other microservices you can fetch at this time and can send aggregated response.

For any data that is available in Microservice A,B,C you will be getting via Gateway. Make sure your gateway is highly available.

Hope that helps . Let me know if you have any questions !

这篇关于微服务创建实体实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆