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

Запуск собственного мессенджера на платформе с аудиторией в десятки миллионов пользователей — это не просто новая фича, а качественный скачок в сложности инфраструктуры. Аналитики прогнозируют захват до 10% рынка, но для инженеров главное — это необходимость построить систему, способную держать миллионы постоянных соединений, гарантировать доставку без дублей и обрабатывать поток сообщений в реальном времени с антифрод-проверками. Классическая CRUD-архитектура объявлений здесь не сработает: речь идёт о stateful-сервисах, сетевых штормах и асинхронных пайплайнах с участием языковых моделей.
Вызов 1: WebSockets и «шторм переподключений»
Маркетплейс исторически работает по модели request-response: HTTP-запрос, ответ, разрыв соединения. Мессенджер требует иного подхода — постоянных каналов связи, чаще всего на базе 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 с ключом партиционирования
chat_id
Вызов 3: Хранение истории и кэширование на масштабе
При успехе проекта объём текстовой истории измерится терабайтами. Хранить всё в PostgreSQL с классическими SELECT и OFFSET — путь к деградации: чтение длинных диалогов будет вешать основную базу.
Разделение горячих и холодных данных
- Горячий слой. Последние 50–100 сообщений каждого активного чата держат в оперативной памяти — Redis или Tarantool. Это даёт субмиллисекундное время отдачи последней истории.
- Холодный слой. Архив уходит в горизонтально масштабируемые NoSQL-решения: Apache Cassandra или ScyllaDB. Они оптимизированы для записей и чтений по первичному ключу, не требуют сложных джойнов и линейно масштабируются добавлением узлов.
Пагинация на курсорах вместо OFFSET
SQL-запросы с
OFFSET
WHERE message_id < :last_seen_id ORDER BY message_id DESC LIMIT 50
Роль ИИ-агентов в пайплайне антифрода
Мессенджер на торговой площадке — магнит для фишинга, спама и социальной инженерии. Объём подозрительного контента вырастет на порядки, поэтому ручная модерация невозможна. ИИ-агенты встраиваются прямо в поток обработки сообщений.
Асинхронный паттерн проверки
- Пользователь нажимает «Отправить».
- Сообщение не идёт сразу в БД и получателю, а попадает в топик Kafka на проверку.
- ИИ-агент (классическая ML-модель или LLM) перехватывает событие, прогоняет через антифрод: анализ ссылок, лексических паттернов, репутации отправителя.
- Если проверка пройдена — сообщение публикуется в чат. Если нет — блокируется, а отправителю уходит системное уведомление.
Критически важно: проверка не должна быть синхронной и блокирующей. Если модель «затупит» на секунде, весь чат встанет. Поэтому используется флаг
status: pending
Заключение: инженерная сложность как маркер проекта
Новость о тестировании мессенджера Авито — это сигнал рынку: компания входит в лигу построения собственных высоконагруженных real-time систем. Отказоустойчивость здесь не решается закупкой железа, а прописывается в каждой строчке: от обработки реконнектов на клиенте и идемпотентных ключей на сервере до шардированного хранения и асинхронных пайплайнов с ИИ. Будет показательно наблюдать, как архитектура поведёт себя при первой серьёзной аварии на проде — именно тогда проявится качество заложенных инженерных решений.


