Изменения документа Диллема обработки сообщений
Редактировал(а) Alexandr Fokin 2024/06/12 16:21
<
отредактировано Alexandr Fokin
на 2024/06/12 15:40
на 2024/06/12 15:40
отредактировано Alexandr Fokin
на 2024/06/12 16:21
на 2024/06/12 16:21
Изменить комментарий:
К данной версии нет комментариев
Комментарий
-
Свойства страницы (1 изменено, 0 добавлено, 0 удалено)
Подробности
- Свойства страницы
-
- Содержимое
-
... ... @@ -1,43 +1,31 @@ 1 -| |((( 2 -Ситуация: 1 +| |(% style="width:929px" %)Ситуация: 3 3 Имеется очередь, из которой приложение читает данные и обрабатывает их. Рассмотрим пример, что приложение имеет следующий цикл обработки сообщения: 4 - 5 5 1) Взять сообщение из очереди 6 6 2) Попытаться выполнить некоторый набор действий на основе данных из сообщения. 7 -Отметим, что обработка сообщения может завершиться как успешно, так и с ошибкой. 8 - 9 -Вариации: 10 - 11 -1] 5 +Отметим, что обработка сообщения может завершиться как успешно, так и с ошибкой.|(% style="width:539px" %) 6 +| |(% style="width:929px" %)1] 12 12 1) Получаем сообщение 13 13 2) Выполняем коммит сообщения (при следующем чтении на вход пойдет следующее сообщение) 14 -3) Выполняем обработку 15 - 16 -2] 9 +3) Выполняем обработку|(% style="width:539px" %)Мы теряем сообщение, в случае если его обработка не завершилась успешно. 10 +| |(% style="width:929px" %)2] 17 17 1) Получаем сообщение 18 18 2) Выполняем обработку 19 -3) Если п.2 выполнен успешно, то выполняем коммит сообщения (при следующем чтении на вход пойдет следующее сообщение) 20 - 21 -Возможные проблемы 22 -1) При потходе 1, мы теряем сообщение, в случае если его обработка не завершилась успешно. 23 -2) При потходе 2, в случае, если после выполнения 2 пункта наше приложение упадет (не успев выполнить пункт 3), то при повторном запуске мы обработаем то-же самое сообщение второй раз. 24 - 13 +3) Если п.2 выполнен успешно, то выполняем коммит сообщения (при следующем чтении на вход пойдет следующее сообщение)|(% style="width:539px" %)В случае, если после выполнения 2 пункта наше приложение упадет (не успев выполнить пункт 3), то при повторном запуске мы обработаем то-же самое сообщение второй раз. 14 +| |(% style="width:929px" %)((( 25 25 Вопросы 26 26 1) Является ли повторная обработка одного и того же сообщения допустимой для нашей системы. 27 27 2) Является ли потеря данных из одного из сообщений критичной для нашей системы. 28 28 3) Возможно в нашей системе производитель сообщение, генерирует сообщени3) Возможно в нашей системе производитель сообщение, генерирует сообщен3) Возможно в нашей системе производитель сообщение, генерирует сообщение повторно через некоторой промежуток времени, если фиксирует, что предыдущее сообщение не было обработано. 29 - 30 - 31 -Более надежное, но более тяжелое решение: 32 -Использование потхода номер 2 совместно с каким-либо более продвинутым механизмом транзакций. Т.е в случае падения приложения транзакция не будет завершена успешно. 19 +)))|(% style="width:539px" %) 20 +| |(% style="width:929px" %)Более надежное, но более тяжелое решение: 21 +Использование подхода номер 2 совместно с каким-либо более продвинутым механизмом транзакций. Т.е в случае падения приложения транзакция не будет завершена успешно. 33 33 Но есть риск если у нас выполняются 2 действия: 34 34 1) коммит транзакции в базе, 2) коммит сообщения. (или в порядке 2, 1) 35 35 В случае падения приложения между указанными шагами, мы все равно можем получить 36 36 либо потерю сообщения (закоммитили сообщение, но не завершили транзакцию), 37 37 либо повторную обработку (завершили транзакцию, но не закоммитил сообщение). 38 -Хоть и вероятность такого события в целом крайне мала. (зависит от системы) 39 -))) 40 -| |((( 27 +Хоть и вероятность такого события в целом крайне мала. (зависит от системы)|(% style="width:539px" %) 28 +| |(% style="width:929px" %)((( 41 41 Замечание: на текущий момент отношу проблему к [[Dual write problem>>doc:Архитектура и модели.Группа\. Распределенные системы.Распределенные системы\. Консистентность.Dual write problem.WebHome]]. 42 42 По хорошему у каждого запроса или хотя бы сообщения должен быть уникальный ключ. Использую его, транзакцию, таблицу с уникальным индексом можно добиться гарантии, что сообщение будет обработано только единожды. Транзакция БД позволяет атомарно зафиксировать и изменения и факт обработки сообщения (по его ключу). 43 43 ... ... @@ -44,8 +44,6 @@ 44 44 Отдельный вопрос: хотим ли мы использовать очередь для приостановки обработки в случае ошибок. Зачастую мы не хотим останавливать обработку из-за одной ошибки. В таком случае важно сохранить проблемное сообщение, но при этом сделать так чтобы обработчик продолжил обрабатывать последующие сообщения. 45 45 46 46 Возможен вариант, когда сообщение просто записывается в БД в статусе ожидает обработку. И фоновый обработчик разбирает таблицу и обрабатывает необходимые строки. 47 -))) 48 -| | 35 +)))|(% style="width:539px" %) 49 49 50 - 51 51