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