TGStat
TGStat
Qidiruv uchun matnni kiriting
Ilg‘or kanal qidiruvi
  • flag Uzbek
    Sayt tili
    flag Russian flag English flag Uzbek
  • Saytga kirish
  • Katalog
    Kanal va guruhlar katalogi Hududiy to‘plamlar Tematik to‘plamlar Платные каналы Kanallar qidiruvi
    Kanal/guruh qo‘shish
  • Reytinglar
    Kanallar reytingi Guruhlar reytingi Postlar reytingi
    Brendlar va shaxslar reytingi
  • Analitika
  • Postlarda qidiruv
  • Telegram'ni kuzatish
  • Targ‘ibot
    Yandex Business orqali reklama TGStat Agency orqali kanallarda reklama TGStat.ru saytida reklama
Art of Code

28 Sep, 19:25

Telegram'da ochish Ulashish Shikoyat qilish

System Design: backend

Эту задачу дают на бэковых собесах в Ozon, и звучит она затрагивает максимально типичную задачу. Есть сервис, который принимает оплату заказа. Когда платёж прошёл, складу нужно узнать, что заказ оплачен и его можно собирать, поэтому сервис отправляет событие в Kafka. Интервьюер описывает ситуацию, в которой платёж уже записан в базу, а Kafka именно в эту секунду недоступна, и просит рассказать, что будет с заказом и как сделать так, чтобы ничего не потерялось. Большинство кандидатов в этот момент рисуют ровно тот код, который потом и разбирают на части.

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

Для этого используют приём, который называется Transactional Outbox. В той же базе, где лежат платежи, заводится отдельная таблица для исходящих событий, и строка в неё пишется в той же транзакции, что и сам платёж. База умеет гарантировать атомарность внутри себя, поэтому после коммита у нас либо есть и платёж, и событие о нём, либо нет ни того, ни другого. В Kafka эти строки перекладывает отдельный процесс, его обычно называют реле. Он берёт из таблицы то, что ещё не отправлено, публикует в брокер и только после подтверждения помечает строку как отправленную. Если реле упадёт между публикацией и пометкой, после перезапуска оно отправит те же строки повторно, и здесь становится понятно, зачем вопрос про дубли задавали в самом начале. Когда экземпляров реле несколько, строки удобно разбирать через SELECT FOR UPDATE SKIP LOCKED, чтобы два процесса не схватили одну запись, а ключом сообщения лучше делать id заказа, тогда все события одного заказа попадут в одну партицию и склад получит их в правильном порядке.

Раз повторы стали нормальной частью системы, получатель обязан с ними справляться. Склад хранит идентификаторы уже обработанных событий и просто пропускает те, что видел раньше. Если про это забыть, Outbox решит проблему у отправителя и тут же создаст новую у склада, где один и тот же заказ начнут собирать дважды. Обычно после этого интервьюер переходит к эксплуатации. Опрашивать таблицу раз в секунду можно, но это нагружает базу и добавляет задержку, поэтому в больших системах изменения часто читают прямо из журнала транзакций с помощью CDC вроде Debezium. Отправленные строки со временем нужно чистить, иначе таблица событий разрастётся быстрее самих платежей. Для мониторинга хватает одной метрики, возраста самой старой неотправленной строки. Если он начал расти, значит реле встало или брокер лежит, и лучше узнать об этом от алерта, чем от склада.

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

Подписаться: @codeof_art
Вступить в чатик: @code_of_art

547 0 13 4
Katalog
Kanal va guruhlar katalogi Kanallar to‘plamlari Kanallar qidiruvi Kanal/guruh qo‘shish
Reytinglar
Telegram-kanallar reytingi Telegram-guruhlar reytingi Postlar reytingi Brendlar va shaxslar reytingi
API
Statistika API'si Postlar qidiruvi API'si API Callback
Kanallarimiz
@TGStat @TGStat_Chat @telepulse @TGStatAPI
O‘qish
Академия TGStat Telegram tadqiqoti 2019 Telegram tadqiqoti 2021 Telegram tadqiqoti 2023
Kontaktlar
Справочный центр Qo‘llab-quvvatlash Email Vakansiyalar
Har xil narsalar
Foydalanuvchi shartnomasi Maxfiylik siyosati Ommaviy oferta
Botlarimiz
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot