Поиск

Технические вызовы разработки мессенджера в Авито: архитектура, отказоустойчивость и антифрод

Технические вызовы разработки мессенджера в Авито: архитектура, отказоустойчивость и антифрод

Запуск собственного мессенджера на платформе с аудиторией в десятки миллионов пользователей — это не просто новая фича, а качественный скачок в сложности инфраструктуры. Аналитики прогнозируют захват до 10% рынка, но для инженеров главное — это необходимость построить систему, способную держать миллионы постоянных соединений, гарантировать доставку без дублей и обрабатывать поток сообщений в реальном времени с антифрод-проверками. Классическая CRUD-архитектура объявлений здесь не сработает: речь идёт о stateful-сервисах, сетевых штормах и асинхронных пайплайнах с участием языковых моделей.

Вызов 1: WebSockets и «шторм переподключений»

Маркетплейс исторически работает по модели request-response: HTTP-запрос, ответ, разрыв соединения. Мессенджер требует иного подхода — постоянных каналов связи, чаще всего на базе WebSockets. В масштабе Авито это означает миллионы одновременных открытых сокетов, каждый из которых потребляет память на сервере и хранит состояние сессии.

Вызов 1: WebSockets и «шторм переподключений»

Проблема состояния и отказов узлов

Любой узел кластера рано или поздно упадёт — это данность распределённых систем. При падении тысячи клиентов теряют связь одновременно и пытаются переподключиться к оставшимся инстансам. Это явление получило название «шторм переподключений» (reconnect storm) и является разновидностью проблемы thundering herd: внезапный пик нагрузки провоцирует каскадный отказ здоровых узлов.

Архитектурные контрмеры в коде

  • Sticky Sessions с учётом состояния. Балансировщик должен направлять клиента на тот же бэкенд-узел, где держится его сокет. Это упрощает управление сессией, но требует умной ребалансировки при масштабировании.
  • Jitter и Exponential Backoff на клиенте. В мобильных приложениях и веб-клиентах закладывается случайная задержка перед повторной попыткой подключения. Без этого синхронный штурм запросов убьёт кластер за секунды.
  • Шардирование соединений и Pub/Sub брокер. Ни один сервер не выдержит все сокеты. Соединения распределяются по шардам, а доставка сообщений между узлами идёт через брокер — Redis Pub/Sub, Apache Kafka или NATS. Брокер становится центральной шиной маршрутизации событий в реальном времени.

Вызов 2: Гарантия доставки и идемпотентность сообщений

В чате нельзя полагаться на простой INSERT в таблицу сообщений. Сеть ненадёжна: пакет может потеряться, а клиент, не дождавшись подтверждения, отправит дубль. Результат — два одинаковых «Привет» у получателя. В высоконагруженных системах выбирают семантику At-least-once (хотя бы одна доставка), так как строгая Exactly-once требует дорогостоящих координаций и повышает латентность.

Ключи идемпотентности на уровне БД

Клиент генерирует уникальный UUID для каждого исходящего сообщения (idempotency key). Сервер проверяет этот идентификатор перед записью: если запись с таким ключом уже существует, вторая попытка отбрасывается без побочных эффектов. Реализация обычно строится на уникальном индексе в базе или атомарном upsert-операторе.

Строгая упорядоченность через партиционирование

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

  1. chat_id
. Все события одного диалога попадают в одну партицию и обрабатываются последовательно одним консьюмером, что исключает перестановку сообщений при параллельной обработке.

Вызов 3: Хранение истории и кэширование на масштабе

При успехе проекта объём текстовой истории измерится терабайтами. Хранить всё в PostgreSQL с классическими SELECT и OFFSET — путь к деградации: чтение длинных диалогов будет вешать основную базу.

Разделение горячих и холодных данных

  • Горячий слой. Последние 50–100 сообщений каждого активного чата держат в оперативной памяти — Redis или Tarantool. Это даёт субмиллисекундное время отдачи последней истории.
  • Холодный слой. Архив уходит в горизонтально масштабируемые NoSQL-решения: Apache Cassandra или ScyllaDB. Они оптимизированы для записей и чтений по первичному ключу, не требуют сложных джойнов и линейно масштабируются добавлением узлов.

Пагинация на курсорах вместо OFFSET

SQL-запросы с

  1. OFFSET
на больших таблицах неэффективны. Правильный паттерн — курсорная пагинация:
  1. WHERE message_id < :last_seen_id ORDER BY message_id DESC LIMIT 50
. Индекс по убывающему идентификатору позволяет мгновенно вырезать нужный диапазон без сканирования предшествующих строк.

Роль ИИ-агентов в пайплайне антифрода

Мессенджер на торговой площадке — магнит для фишинга, спама и социальной инженерии. Объём подозрительного контента вырастет на порядки, поэтому ручная модерация невозможна. ИИ-агенты встраиваются прямо в поток обработки сообщений.

Роль ИИ-агентов в пайплайне антифрода

Асинхронный паттерн проверки

  1. Пользователь нажимает «Отправить».
  2. Сообщение не идёт сразу в БД и получателю, а попадает в топик Kafka на проверку.
  3. ИИ-агент (классическая ML-модель или LLM) перехватывает событие, прогоняет через антифрод: анализ ссылок, лексических паттернов, репутации отправителя.
  4. Если проверка пройдена — сообщение публикуется в чат. Если нет — блокируется, а отправителю уходит системное уведомление.

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

  1. status: pending
— сообщение доставляется интерфейсно, но помечается как неподтверждённое. Через секунду приходит финальный вердикт: подтверждение или удаление с уведомлением. Такой подход сохраняет отзывчивость UI и изолирует нестабильность ML-инференса от критического пути доставки.

Заключение: инженерная сложность как маркер проекта

Новость о тестировании мессенджера Авито — это сигнал рынку: компания входит в лигу построения собственных высоконагруженных real-time систем. Отказоустойчивость здесь не решается закупкой железа, а прописывается в каждой строчке: от обработки реконнектов на клиенте и идемпотентных ключей на сервере до шардированного хранения и асинхронных пайплайнов с ИИ. Будет показательно наблюдать, как архитектура поведёт себя при первой серьёзной аварии на проде — именно тогда проявится качество заложенных инженерных решений.

Читайте также на сайте

—
23:44
8
Нет комментариев. Ваш будет первым!