Лучшая практика для обработки асинхронного взаимодействия?

10

Недавно завершен проект по обработке кредитных карт. Одна из трудностей, с которыми я столкнулся, была обработка задержки / возможного сбоя уведомительных сообщений. Самый сложный пример был:

  • внешняя система, отправляющая запрос на оплату
  • моя система превратила этот запрос в запрос к платежному шлюзу
  • отправка пользователя на шлюз
  • ждет, пока пользователь выполнит платеж
  • пользователь возвращается в мою систему, но удерживается до тех пор, пока система не получит уведомление об успехе / сбое
  • Отправка пользователя обратно во внешнюю систему в зависимости от сбоя

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

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

Достаточно сложно!

Но это, должно быть, было решено несколько миллионов раз, так какова лучшая практика?

Я вижу, что мое будущее будет заключаться в том, чтобы писать обработку между всеми этими системами и управлять временными задержками и возможными сбоями в сети, поэтому я хочу следовать передовым методам.

Рекомендации по книге / статье были бы отличными.

Заранее спасибо!

user86928
источник

Ответы:

13

При построении распределенных систем разница между «синхронной» системой и «асинхронной» системой заключается в следующем: синхронная система имеет верхние границы вычислений и времени доставки сообщений. Итак: у вас есть асинхронная система, в которой определенные события не имеют этих известных верхних границ. Как вы справляетесь с этим?

  1. Если эти асинхронные процессы имеют вероятностные верхние границы, вы можете использовать тайм-ауты, чтобы заставить вашу систему работать как частично синхронная система. Если время ответа 98-го процентиля платежного шлюза составляет 5 секунд, то 5-секундный тайм-аут сделает 98% ваших запросов успешными, а остальные 2% просто не пройдут. Это означает, что теперь у вас есть известная верхняя граница того, как долго этот процесс будет успешным или неудачным. Это вероятностное обнаружение сбоев является критически важным инструментом для превращения асинхронных систем в синхронные системы.

  2. Ведите постоянную запись этих событий, чтобы вы могли восстановить состояние системы в случае сбоя системы. Если ваш обработчик платежного шлюза хранит эти события в энергозависимой памяти, и он выходит из строя, значит, вы облажались.

  3. Каждая сложная транзакция, по сути, представляет собой серию преобразований состояний, основанных на отправке и получении сообщений (событий) внутри системы. Похоже, что вы неформально моделируете это, используя свою «запись ожидающих транзакций», но я бы посоветовал вам пойти дальше: для каждой транзакции, которой вам нужно управлять, создайте формальный конечный автомат, который описывает его, и ведите долговременную запись ее текущего состояния. , Вы обнаружите, что эти конечные автоматы просты для понимания, просты в тестировании и предоставляют столь необходимую информацию об этих процессах как для вас, так и для ваших пользователей.

Чем более асинхронна ваша система, тем более формальной и явной должна быть ваша ситуация при управлении этими сложными преобразованиями четных состояний. Тайм-ауты, длительная регистрация событий и конечные автоматы - лучшая практика здесь. Вот почему Erlang OTP, например, основывает большую часть поведения своего приложения на модели конечного автомата.

Для справки, я не нашел ничего лучше, чем « Введение в надежное и безопасное распределенное программирование» . Это даст вам прочную алгоритмическую основу для понимания как синхронных, так и асинхронных систем из первых принципов.

Рейн Хенрикс
источник