Микросервисы Создание Entity Реализация - PullRequest
2 голосов
/ 18 июня 2019

Это дополнительный вопрос к моей проблеме, обрисованный в общих чертах здесь .

Шлюз служит точкой входа в приложение, к которому выполняется каждый запрос от клиента.Затем шлюз назначает запрос ответственным микросервисам и также обрабатывает аутентификацию.

В этом случае шлюз прослушивает HTTP POST /bok и уведомляет Microservice A о создании книги.Таким образом, Microservice A несет ответственность за управление и хранение всего сущности книги.


Следующий псевдокод представляет собой упрощенную реализацию этой архитектуры:

Связь через очередь queue communication

Шлюз

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

Но я не совсем уверен в этом из-за следующих причин:

  1. Слушатель для использования BookCreated в Gateway будет воссоздан каждый раз, когда пользователь запрашивает создание новой книги
  2. Что, если 2 пользователя одновременно создадут книгу и будет возвращена не та книга?
  3. Я не знаю, как получить дополнительные данные (например, getUserFromOtherMicroService)

Вот почему я думаю о реализации этой архитектуры:

Прямая и очередь связи direct communication

Шлюз

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, когда возвращаю книгу после создания?(потому что я должен только возвратить OK или ERROR)
  2. Разве неэффективно сделать еще один HTTP-запрос в системе микросервисов?

1 Ответ

1 голос
/ 19 июня 2019

Основано на комментариях выше.

Подход 1

В этом случае ваш API-шлюз будет использоваться для отбрасывания сообщения в очереди.Этот подход более уместен, если ваш процесс займет много времени и у вас есть работники очереди, которые собирают сообщения и обрабатывают их.Но ваша клиентская сторона должна опросить, чтобы получить результаты.Скажем, вы ищете авиабилет.Вы бросаете сообщение.Вы получите ID для опроса.Ваш клиент будет продолжать опрос, пока не станут доступны результаты.

Но в этом случае у вас возникнет проблема, когда вы отбросите сообщение о том, как вы собираетесь сгенерировать идентификатор, который клиент будет опрашивать?Назначаете ли вы идентификатор для сообщения на шлюзе, помещаете его в очередь и возвращаете ли тот же идентификатор для опроса клиента, чтобы получить результат?Опять же, этот подход хорош для веб-сценария.

Подход 2

Поскольку ваш API-шлюз является пользовательским приложением, которое будет обрабатывать аутентификацию и перенаправлять запрос в соответствующую службу.Ваша Microsvc A создаст книгу и опубликует событие, а ваши Microservice B и C будут ее использовать.Ваш шлюз будет ожидать, пока микросервис А вернет ответ с идентификатором (или метаданными события вновь созданного объекта) книги, которая создана, чтобы вы не опрашивали ее позже, а у клиента она есть.Если вы хотите, вы можете получить дополнительную информацию от других микросервисов, которые вы можете получить в это время и отправить агрегированный ответ.

Для любых данных, которые доступны в Microservice A, B, C, вы будете получать через шлюз.Убедитесь, что ваш шлюз очень доступен.

Надеюсь, это поможет.Дайте мне знать, если у вас есть какие-либо вопросы!

...