← Назад к списку
Системный дизайнАрхитектура и алгоритмыSenior

Спроектируйте мессенджер уровня WhatsApp: личные и групповые чаты, статусы доставки и прочтения, работа при нестабильной сети.

Короткий ответ

  • Постоянное соединение: WebSocket, для мобильных — плюс push
  • Сервис-шлюз держит соединения, реестр знает, кто где подключён
  • Сообщения персистентны до подтверждения доставки
  • Порядок в чате задаёт серверный монотонный номер
  • Групповой чат — fan-out по участникам через очередь
  • Идемпотентность по client message id против дублей
  • Офлайн-пользователю сообщение ждёт в inbox и уходит пушем

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

Как сказать вслух

пример ответа

Я разделю систему на шлюзы, которые держат WebSocket-соединения, и сервис сообщений, который пишет всё в хранилище до подтверждения. Порядок внутри чата обеспечу серверным номером сообщения. Дубли при ретраях отсеку по идентификатору, который генерирует клиент.

Подробный ответ

Основной ответ

Клиент держит WebSocket с одним из шлюзов; реестр присутствия (например, в Redis) сопоставляет пользователя и шлюз. Отправка: клиент шлёт сообщение со своим client id, сервис сообщений сохраняет его в хранилище (Cassandra/HBase, партиционирование по chat id, кластеризация по номеру сообщения), присваивает серверный монотонный номер и отдаёт ack. Затем доставка: по реестру находим шлюз получателя и пушим; офлайн-получателю сообщение остаётся в его inbox и дублируется мобильным пушем. Статусы sent/delivered/read — отдельные служебные события. Группы — fan-out по списку участников через очередь. Ретраи клиента безопасны: сервер дедуплицирует по client id.

Ключевые моменты

  • Порядок сообщений. Полагаться на часы клиентов нельзя; монотонный номер в рамках чата выдаёт сервер, и клиенты сортируют по нему.
  • Надёжная доставка. Сообщение считается принятым только после записи в хранилище; клиент ретраит до ack, сервер дедуплицирует — получаем at-least-once без дублей для пользователя.
  • Реестр присутствия. Пользователи размазаны по шлюзам, поэтому нужен быстрый справочник «кто на каком шлюзе» с heartbeat и очисткой мёртвых сессий.
  • Большие группы. Fan-out на тысячи участников делается асинхронно воркерами; для очень больших групп доставку заменяют подпиской на канал.

Практический контекст

Интервьюер ждёт обсуждения гарантий: порядок, exactly-once для пользователя, поведение при обрыве сети и переподключении (синхронизация по последнему полученному номеру). Уточните: нужен ли E2E-шифрование, история на новых устройствах, максимальный размер группы, индикатор «печатает». Сильный ход — описать переподключение клиента и догрузку пропущенного как обычный pull по номеру.

Частые ошибки

  • Доставляют сообщения напрямую между шлюзами без персистентности — при падении узла сообщения теряются
  • Упорядочивают чат по таймстемпам клиентов, которые расходятся между устройствами
  • Забывают сценарий переподключения: клиент после обрыва не знает, что пропустил

ИП Кочкин Алексей Сергеевич · ИНН 390509026279 · ОГРНИП 325390000030973 · jiniys2005@yandex.ru