Этот архитектурный дизайн включает три узла: Webapp, Artemis и Backend. В случае непредвиденного сбоя одного из этих узлов требуется восстановление системы, иногда вместе с восстановлением данных. Ниже приведена схема восстановления.
Webapp сам по себе не хранит состояние данных; единственное хранилище — это ResultCache. Утрата данных в ResultCache не является проблемой. Поэтому при сбое Webapp достаточно просто перезапустить его.
Артемис представляет собой промежуточный слой сообщений, который можно рассмотреть в двух сценариях.
Сценарий 1: Webapp отправляет запрос Request Артемису, который затем передает его Backend. При сбое Артемиса существует три возможных ситуации:
Первые две ситуации можно рассматривать как случаи, когда запрос не был доставлен до backend, поэтому потеря запроса не имеет значения. В третьей ситуации считается, что запрос был успешно доставлен, и нет необходимости в специальном обработке.
Сценарий 2: Backend отправляет результат Result Артемису, который затем передает его Webapp. При сбое Артемиса также существуют три возможные ситуации:1. Backend -> Artemis завершился ошибкой
Проверка заказа пользователя (что указывает на успешность оформления заказа) происходит вне этого узла, так что потерю результата можно принять.
Объединяя эти два сценария, можно сделать вывод, что при сбое Артемиса достаточно просто перезапустить его.
Backend отвечает за выполнение бизнес-логики (определение возможности оформления заказа) и запись результата в базу данных. При сбое Backend может произойти потеря данных. Однако мы используем концепцию конечной согласованности вместо транзакций, поэтому восстановление потерянных данных требует использования логов.
Рассмотрим основные шаги обработки запроса Backend:
crash point 1 Получение запроса
crash point 2 Выполнение бизнес-логики
crash point 3 Подготовка записи в базу данных
crash point 4 Выполнение операции записи в базу данных
crash point 5 Завершение записи в базу данныхДалее рассмотрим способы обработки каждого из этих точек отказа:
Пункт сбоя 1, в этом случае сбой неважен, потеря запроса допустима
Пункт сбоя 2, в этом случае сбой неважен, потеря запроса допустима
Пункт сбоя 3, в этом случае сбой приведёт к потере данных
Пункт сбоя 4, в этом случае сбой приведёт к потере данных
Пункт сбоя 5, в этом случае сбой неважен, так как все данные уже записаныИз этого можно заключить, что действительно важно обратить внимание на сбои, происходящие на шагах 3 и 4. Для решения этой проблемы нам следует создать восстановительную систему, которая будет достаточно простой. Её можно свести к следующим шагам:
Перед тем как внести изменения в базу данных, набор команд (операции над базой данных) записывается в лог-файл. Набор команд состоит из нескольких команд, так как одна операция массового внесения данных может содержать несколько команд.
После завершения внесения данных, результат выполнения каждой команды записывается в лог-файл. Здесь каждая команда рассматривается отдельно, поскольку наши команды выполняются параллельно.
При возникновении сбоев мы запускаем режим восстановления, последовательно читаем лог-файлы, выявляем незавершенные или неудачно выполненные команды и повторно выполняем их.
Внимание: данное описание представляет собой концепцию дизайна, которая не реализована в данном проекте.
Вот пример формата лог-файла:
{header} : [EMIT]A={Json}/DELIMITER/B={Json}/EOL/
{header} : [OPTM]A={Json}/EOL/
{header} : [EXEC]A={Json}/EOL/
{header} : [FAIL]A={Json}/EOL/
```{header}: Заголовок строки лога, обычно это базовая информация, такая как время, PID процесса, номер потока и т.д.
/DELIMITER/: Разделитель
/EOL/: Конец строки
[EMIT]: Отправка
[OPTM]: Оптимизация, команда была оптимизирована, если две команды относятся к одному и тому же объекту, то требуется выполнение только последней команды, а первая не нужна
[EXEC]: Успешное выполнение
[FAIL]: Неудачное выполнение
A,B: Имя команды
{Json}: JSON-строка команды
```Особое внимание следует обратить на наличие **основного бизнес-ключа** для каждой команды. Например, товарный ID является основным бизнес-ключом в нашем случае.
**Основной бизнес-ключ** важен потому что при наличии нескольких команд для одного и того же товарного ID, неудачное выполнение одной из них не обязательно требует её восстановления. Например, команда `ItemAmountUpdateCommand`:
1. [EMIT]: {id: "abcdef", itemId:1, amount=100}/DELIMITER/{другие команды}
1. [FAIL]: {id: "abcdef", itemId:1, amount=100}
1. [EMIT]: {id: "xyzabc", itemId:1, amount=90}/DELIMITER/{другие команды}
1. [EXEC]: {id: "xyzabc", itemId:1, amount=90}
В этом примере команда `[abcdef]` не выполнилась, но затем была успешно выполнена другая команда `[xyzabc]`, которая также относится к тому же товарному ID. Таким образом, неудачное выполнение первой команды было компенсировано успешным выполнением второй.
[src-ItemAmountUpdateCommand]: jms-server/src/main/java/me/chanjar/jms/server/command/item/ItemAmountUpdateCommand.java
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )