Изменения документа Диллема обработки сообщений

Редактировал(а) Alexandr Fokin 2024/06/12 16:21

<
От версии < 5.8
отредактировано Alexandr Fokin
на 2024/06/12 16:21
К версии < 5.2 >
отредактировано Alexandr Fokin
на 2023/01/23 23:55
Изменить комментарий: Update document after refactoring.

Комментарий

Подробности

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