first-programmer
@first-programmer
Backend software engineer

Что лучше для опроса статусов платежей, крон задача или отложенные сообщения через rabbitmq сервер?

Всем привет. На работе сейчас обсуждаем, как отрефакторить систему. Есть проблема. Ядро системы обращается к внутренним сервисам проведения платежей для инициализации платежа. Потом ядро начинает ходить за статусами платежей к этим сервисам, типа а вот такой платеж готов или нет? Сообщения о проверке статуса формируется ядром, это простое отложенное сообщение в очередь. Проблема в том, что ядро постоянно спамит проверкой статусов наши сервисы.

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

Заранее уточню - колбек от оператора связи получает только один платежный сервис, другие операторы так не делают. Поэтому в этом сервисе все просто - получил колбек - отправил ядру уведомление.

У остальных операторов такой роскоши нет и мы пока вот два решения рассматриваем.

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

- Отложенные сообщения внутри платежного сервиса. Пришло сообщение на инициализацию платежа, мы его выполнили и в конце сразу отправляем отложенное сообщение на проверку статуса, которое почитается из очереди через нужное время.

У первого варианта вижу из недостатков это то, что по умолчанию обычная крон задача не может выполняться чаще 1 раза в минуту и нужно делать костыль с демоном или что-то прикручивать еще к киберу. Плюс она будет выполняться иногда в холостую, когда нет платежей не в финальном статусе, хотя это наверно мелочь? Из плюсов - простая логика, то есть очень легко отслеживать и понимать работу кода. Просто крон контроллер и нужные действия.

У второго варианта из минусов вижу, что нужно добавлять и в безрого запутанную логику дополнительные отправки сообщений в очередь на проверку статуса. Ведь у нас есть один платежный сервис, где логика не сводится к простому - отправил запрос на платеж и проверил статус. Тут надо и выпустить токен через aok, и проверить его статус и потом уже только провести платеж и его статус проверить. Плюс разные отмены и возвраты. Из плюсов - нет крон задач и бизнес логика в одном месте, плюс кроны в холостую не вызываются.

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

Второй вариант мне правда нравится тем, что он выглядит как-то более органично, чтоли. Ты отправляешь запрос на инициализацию платежа и сервис сам там по очередям себе раскидывает что надо. Но у него я еще вижу минус в том, что крон задача - это надежно. Пока она не доведет до нужного состояния платеж, она не успокоится. А вот отправка отложенных сообщений это возможные косяки - ты отправил в сервис запрос на инициализацию, у тебя оно пришло, сервис отправил платеж оператору, мы запушили отложенное сообщение о проверке статуса в очередь и вдруг у тебя сервер очередей лежал в это время? Или что-то в коде отвалилось и запрос не смог отправиться? И вот у тебя висит платеж. с нефинальным статусом, но его никто не попробует переподнять.

Может сочетать оба варианта и сделать задачи как подстраховку?

Вот хочу посоветоваться, какой из вариантов лучше и что бы вы предложили сами?
  • Вопрос задан
  • 183 просмотра
Пригласить эксперта
Ответы на вопрос 1
myks92
@myks92
Нашёл решение — пометь вопрос ответом!
Ни тот и ни другой. Переходите на Message Driven архитектуру. Вместо того, чтобы делать постоянные запросы кроном к сервису лучше сделайте публикацию события в RabbitMQ.

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

При работе с RabbitMQ нужно помнить:
  1. Он гарантирует как минимум 1 раз доставить ваше сообщение. Это значит, что вполне может быть дубль и вам нужно быть готовым к этому. То есть делать идемпотентный консьюмер.
  2. Сообщение может быть не доставлено по причине недоступности сервиса очередей, так же и сообщение может быть потеряно, в том числе из-за недоступности сервиса. Поэтому вам нужно гарантировать доставку через Outbox.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы