Job 2026 md

title: Алекс Сюй, «System Design. Подготовка к сложному интервью» (Vol. 1, рус. изд.) — глава 10: Система уведомлений source: materials/System Design. Подготовка к сложному интервью.pdf, стр. 166–182 конспект: TASK-45.38, извлечено pymupdf 2026-09-17; ниже полный «грязный» текст главы + выжимка статус: выжимка и перенос в knowledge-base.md / methodology.md / classic-designs.md — см. _map.md


Глава 10. Система уведомлений

Выжимка

Каналы: iOS — APNs, Android — FCM, SMS — Twilio/Nexmo, email — SendGrid/Mailchimp. Оценки: 10 млн push + 1 млн SMS + 5 млн email в день.

Сбор контактов: при регистрации/установке → таблицы user (email, phone) и device (device token; устройств может быть много).

Эволюция архитектуры: один сервер уведомлений (SPOF, нет масштабирования, узкое место) → сервисы → серверы уведомлений (API + валидация + шаблоны) → очереди по типам (отдельная очередь на push-iOS/push-Android/SMS/email — отказ одного провайдера не роняет остальные) → воркеры → сторонние сервисы. БД и кэш вынесены.

Надёжность: уведомления не теряются — пишем в журнал уведомлений (БД) + retry; дубликаты возможны (at-least-once) → дедуп по ID события; rate limiting на получателя (иначе отписки); безопасность — appKey/appSecret, только проверенные клиенты; мониторинг длины очередей (растёт → добавляем воркеров); аналитика (открытия, клики, отписки) + настройки opt-in пользователя.

Перенос: KB §14.5 (уведомления — строительный блок: очереди по каналам, журнал, retry, дедуп).

Полный текст (грязная выгрузка)

10 ПРОЕКТИРОВАНИЕ СИСТЕМЫ УВЕДОМЛЕНИЙ В последние годы система уведомлений активно используется во многих приложениях. Она сообщает пользователям важную информацию вроде актуальных новостей, обновлений продуктов, событий, коммерческих пред­ ложений и т. д. Уведомления стали неотъемлемой частью нашей жизни. В этой главе вам предложено спроектировать систему уведомлений. Речь идет не только о мобильных push-уведомлениях, но и об SMS и электрон­ ных письмах. Примеры каждого типа уведомлений показаны на рис. 10.1. Push-уведомление Электронное письмо SMS Рис. 10.1

Проектирование системы уведомлений      167 ШАГ 1: ПОНЯТЬ ЗАДАЧУ И ОПРЕДЕЛИТЬ МАСШТАБ РЕШЕНИЯ Создание масштабируемой системы, которая ежедневно отправляет миллионы уведомлений, — непростая задача, которая требует глубокого понимания соответствующей экосистемы. Эта задача специально сфор­ мулирована так, чтобы допускать свободную трактовку. Чтобы прояснить все требования, вам необходимо задать уточняющие вопросы. Кандидат: «Какого рода уведомления поддерживает система?» Интервьюер: «Push-уведомления, SMS-сообщения и электронные письма». Кандидат: «Это система реального времени?» Интервьюер: «Пусть это будет система мягкого реального времени. Мы хотим, чтобы пользователь получал уведомления как можно раньше. Но, если система сильно нагружена, допускаются небольшие задержки». Кандидат: «Какие устройства поддерживаются?» Интервьюер: «Устройства iOS и Android, а также ноутбуки и ПК». Кандидат: «Что инициирует уведомления?» Интервьюер: «Уведомления могут быть инициированы клиентскими приложениями или запланированы на стороне сервера». Кандидат: «Есть ли у пользователей возможность отписаться от уведомлений?» Интервьюер: «Да, пользователи, решившие отписаться, больше не будут получать уведомления». Кандидат: «Сколько уведомлений отправляется ежедневно?» Интервьюер: «10 миллионов мобильных push-уведомлений, 1 милли­ он SMS-сообщений и 5 миллионов электронных писем». ШАГ 2: ПРЕДЛОЖИТЬ ОБЩЕЕ РЕШЕНИЕ И ПОЛУЧИТЬ СОГЛАСИЕ В этом разделе представлена общая архитектура с поддержкой разных ти­ пов уведомлений: push-уведомлений для iOS и Android, SMS-сообщений и электронных писем. Мы рассмотрим следующие темы:

168      ГЛАВА 10

разные типы уведомлений;

процесс сбора контактной информации;

процесс отправки/получения уведомлений. Разные типы уведомлений Для начала рассмотрим общий принцип работы уведомлений каждого типа. Push-уведомления для iOS APNs Провайдер iOS Рис. 10.2 Отправка push-уведомлений для iOS требует наличия трех основных компонентов.

Провайдер. Провайдер формирует и отправляет запрос сервису APN (Apple Push Notification). Для создания уведомления он ис­ пользует следующие данные: Š Š маркер устройства — уникальный идентификатор, который ис­ пользуется для отправки push-уведомлений; Š Š полезные данные — словарь JSON с содержимым уведомления. Например: { "aps":{ "alert":{ "title": "Game Request", "body":"Bob wants to play chess", "action-loc-key":"PLAY" }, "badge":5 } }

Проектирование системы уведомлений      169

APN — удаленный сервис, предоставляемый компанией Apple для доставки push-уведомлений на устройства iOS.

Устройство iOS — конечный клиент, который получает push- уведомления. Push-уведомления для Android Для отправки уведомлений устройствам Android используется похожий механизм, но вместо APN обычно применяется сервис FCM (Firebase Cloud Messaging). Android FCM Провайдер Рис. 10.3 SMS-сообщения Для рассылки SMS-сообщений обычно используются такие сторонние сервисы, как Twilio [1], Nexmo [2] и многие другие. Большинство из них являются коммерческими. Сервис SMS SMS Провайдер Рис. 10.4 Электронные письма У компаний есть возможность сконфигурировать собственные почтовые серверы, но многие из них отдают предпочтение коммерческим сервисам. Sendgrid [3] и Mailchimp [4] — одни из самых популярных; они обеспе­

170      ГЛАВА 10 чивают повышенную скорость доставки и включают системы анализа данных. Почтовый сервис Электронное письмо Провайдер Рис. 10.5 На рис. 10.6 показана архитектура с поддержкой всех сторонних сервисов. Email iOS Android SMS Сервис SMS Электронное письмо APNs FCM Сторонние сервисы Рис. 10.6

Проектирование системы уведомлений      171 Процесс сбора контактной информации Для отправки уведомлений нам нужно собрать маркеры, телефонные но­ мера или адреса электронной почты мобильных устройств. Как показано на рис. 10.7, при установке нашего приложения или во время регистрации пользователь предоставляет контактную информацию, которую серверы API сохраняют в базе данных. Балансировщик нагрузки Серверы API БД сохранение контактной информации во время установки приложения или регистрации Пользо- ватель Рис. 10.7 На рис. 10.8 показаны упрощенные таблицы базы данных для хранения контактной информации. Адреса электронной почты и телефонные но­ мера хранятся в таблице user, а маркеры устройств — в таблице device. У пользователя может быть несколько устройств, а уведомления могут отправляться каждому из них. Рис. 10.8 Процесс отправки/получения уведомлений Сначала рассмотрим общую архитектуру, а затем предложим некоторые оптимизации.

172      ГЛАВА 10 Общая архитектура На рис. 10.9 представлена общая архитектура. Ниже мы разберем каждый ее компонент. Система уведомлений Сервис 1 Сервис 2 Сервис N . . . Сервис SMS Почтовый сервис APNs FCM Сторонние сервисы Email iOS Android SMS Рис. 10.9

Сервисы от 1 до N. Это могут быть микросервисы, задания cron или распределенная система, которая инициирует отправку уве­ домлений с помощью событий. Например, система биллинга от­ правляет клиентам электронные письма с напоминаниями о не­ обходимости оплаты, а интернет-магазин отправляет покупателям SMS-сообщения с информацией о дате доставки товара.

Система уведомлений. Это главный механизм отправки/полу­ чения уведомлений. Чтобы начать с чего-то простого, будем ис­ пользовать один сервер, который предоставляет API-интерфейсы для сервисов от 1 до N и формирует содержимое уведомлений для сторонних сервисов.

Проектирование системы уведомлений      173

Сторонние сервисы. Сторонние сервисы отвечают за доставку уведомлений пользователям. При интеграции с ними нужно уделять внимание расширяемости. Благодаря расширяемости система становится гибкой и позволяет легко подключать и от­ ключать сторонние сервисы. Еще один важный фактор: сторонний сервис может стать недоступным в будущем или при выходе на новые рынки. Например, сервис FCM недоступен в Китае, по­ этому вместо него там используются такие альтернативы, как Jpush, PushY и т. д.

iOS, Android, SMS, электронные письма. Пользователи получают уведомления на свои устройства. У этой архитектуры есть три проблемы.

Единая точка отказа из-за наличия лишь одного сервера.

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

Узкое место производительности. На обработку и отправку уве­ домлений может уходить много ресурсов. Например, генерация HTML-страниц и ожидание ответов от сторонних сервисов может занять какое-то время. Система, которая берет на себя всю работу, может оказаться перегруженной, особенно в часы пик. Улучшенная общая архитектура С учетом недостатков исходной архитектуры внесем следующие улуч­ шения:

выносим базы данных и кэш за пределы сервера уведомлений;

добавляем больше серверов уведомлений и настраиваем автомати­ ческое горизонтальное масштабирование;

добавляем очереди сообщений для разделения компонентов си­ стемы. Улучшенная общая архитектура показана на рис. 10.10.

174      ГЛАВА 10 Серверы уведом- лений Push-уведомления iOS Очередь SMS Очередь эл. писем Рабочие узлы Push-уведомления Android Email iOS Android SMS APNs FCM БД Сервис 1 Сервис 2 Сервис N повторить в случае ошибки 1 2 3 6 5 4 . . . Рабочие узлы Рабочие узлы Рабочие узлы Сервис SMS Почтовый сервис Сторонние сервисы КЭШ КЭШ КЭШ Рис. 10.10 Лучше разобрать эту диаграмму слева направо.

Сервисы от 1 до N представляют разные сервисы, которые исполь­ зуют API серверов уведомлений.

Серверы уведомлений. Они дают следующие возможности: Š Š API для отправки уведомлений, доступные только внутри или для проверенных клиентов (чтобы предотвратить спам); Š Š базовая проверка адресов электронной почты, телефонных номеров и т. д.; Š Š извлечение из БД или информации, необходимой для форми­ рования уведомления; Š Š запись уведомлений в очереди сообщений для параллельной обработки. Вот пример API-интерфейса для отправки электронного письма: POST https://api.example.com/v/sms/send

Проектирование системы уведомлений      175 Тело запроса: { "to": [ { "user_id":123456 } ], "from":{ "email": "from_address@examle.com" }, "subject": " Hello, World! " "content": [ { "type": "text/plain", "value": "Hello, World" } ] }

Кэш — пользовательские данные, информация об устройстве и ша­ блоны уведомлений.

БД хранит данные о пользователях, уведомлениях, настройках и пр.

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

Рабочие узлы — список серверов, которые достают события об уведомлениях из очереди сообщений и отправляют их соответству­ ющим сторонним сервисам.

Сторонние сервисы. Они уже обсуждались в описании исходной архитектуры.

iOS, Android, SMS, электронные письма. Они уже обсуждались в описании исходной архитектуры. Теперь давайте посмотрим, как совместная работа всех этих компонентов позволяет отправить уведомление. 1. Сервис вызывает API, предоставленные серверами уведомлений.

176      ГЛАВА 10 2. Серверы уведомлений извлекают из БД метаданные, такие как информация о пользователе, маркер устройства и настройки. 3. В соответствующую очередь отправляется событие об уведом­ лении для последующей обработки. Например, событие о push- уведомлении для iOS попадает в очередь iOS PN. 4. Рабочие узлы достают события об уведомлениях из очередей со­ общений. 5. Рабочие узлы отправляют уведомления сторонним сервисам. 6. Сторонние сервисы отправляют уведомления на устройства поль­ зователей. ШАГ 3: ПОДРОБНОЕ ПРОЕКТИРОВАНИЕ В разделе, посвященном общей архитектуре, мы обсудили разные типы уведомлений, процесс сбора контактной информации и процесс отправ­ ки/получения уведомлений. Теперь углубимся в следующие темы:

Надежность.

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

Обновленная архитектура. Надежность При проектировании системы уведомлений в распределенном окружении необходимо ответить на несколько важных вопросов. Как предотвратить потерю данных? Одно из важнейших требований к системе уведомлений — она не должна терять данные. Уведомления, как правило, могут задерживаться или при­ ходить в другом порядке, но они никогда не теряются. Для удовлетворе­ ния этого требования система записывает уведомления в лог, который

Проектирование системы уведомлений      177 хранится в базе данных, и реализует механизм повторных вызовов. Это показано на рис. 10.11. Push-уведомления iOS Рабочие узлы APNs Журнал уведомлений Рис. 10.11 Доходят ли уведомления до получателя строго в единственном экземпляре? Если коротко, то нет. В большинстве случаев уведомление приходит ровно один раз, но из-за распределенной природы нашей системы порой случается дублирование. Чтобы это происходило реже, мы используем механизм устранения дубликатов и тщательно обрабатываем каждый не­ удачный случай. Логика в этом случае проста. При поступлении события об уведомлении мы сначала проверяем его ID, чтобы узнать, приходило ли оно раньше. Если мы его уже встречали, оно отклоняется. В противном случае мы его отправляем. Если вас интересует, почему мы не можем гарантировать доставку строго в единственном экземпляре, обратитесь к справочному материалу [5]. Дополнительные компоненты и функции Мы уже обсудили то, как собирать контактную информацию пользователей и отправлять/получать уведомления. Но система уведомлений этим не огра­ ничивается. Здесь речь пойдет о дополнительных компонентах и функциях, таких как повторное использование шаблонов, параметры уведомлений, отслеживание событий, система мониторинга, ограничение трафика и т. д.

178      ГЛАВА 10 Шаблон уведомлений Крупные системы ежедневно отправляют миллионы уведомлений, многие из которых имеют похожий формат. Чтобы не генерировать их все с нуля, мы используем шаблоны. Шаблон содержит отформатированный текст с возможностью изменения параметров, стилей, ссылок для отслежива­ ния и т. д. Это позволяет создавать уникальные уведомления. Пример показан ниже. ТЕЛО СООБЩЕНИЯ: Вы об этом мечтали. Мы на это решились. [НАЗВАНИЕ ПРОДУКТА] снова в продаже — только до [ДАТА]. CTA: Заказать сейчас. Или сохранить [НАЗВАНИЕ ПРОДУКТА]. К преимуществам использования шаблонов уведомлений можно отнести неизменность формата, уменьшение количества ошибок и экономию времени. Параметры уведомлений Количество уведомлений, которые ежедневно получают пользователи, может легко превысить пределы разумного. В связи с этим многие веб- сайты и приложения дают пользователям возможность гибкого управ­ ления своими уведомлениями. Эта информация хранится в таблице с параметрами уведомлений, состоящей из следующих полей: user_id bigInt channel varchar # push-уведомления, электронные письма или SMS opt_in boolean # получать уведомления Прежде чем отправлять пользователю какие-либо уведомления, мы про­ веряем, желает ли он их получать. Ограничение трафика Чтобы не заваливать пользователя уведомлениями, мы можем ограни­ чить их количество. Это важно, потому что пользователь может вообще отключить все уведомления, если мы будем отправлять их слишком часто.

Проектирование системы уведомлений      179 Механизм повторных вызовов Уведомление, которое не удается отправить стороннему сервису, до­ бавляется в очередь сообщений для повторной попытки. Если проблема остается, информация об этом передается разработчикам. Безопасность push-уведомлений В приложениях для iOS и Android защита API-интерфейсов push- уведомлений основана на appKey и appSecret [6]. Отправлять push- уведомления с помощью этих API-интерфейсов могут только аутен­ тифицированные или проверенные клиенты. Подробнее об этом можно почитать в справочном материале [6]. Мониторинг отложенных уведомлений Одной из ключевых метрик мониторинга является общее число ожи­ дающих уведомлений. Если оно становится большим, это означает, что рабочие узлы не успевают обрабатывать события об уведомлениях. Чтобы не задерживать доставку уведомлений, нужно добавить больше рабочих узлов. На рис. 10.12 (см. [7]) показан пример сообщений, ожидающих обработки. Рис. 10.12 Отслеживание событий Чтобы лучше понимать поведение пользователей, необходимо отслежи­ вать такие метрики, как процент открытия уведомлений, процент кликов

180      ГЛАВА 10 и вовлеченность. Отслеживание событий реализует аналитический сер­ вис, который обычно должен быть интегрирован в систему уведомлений. На рис. 10.13 показан пример событий, которые могут отслеживаться для последующего анализа. ошибка начало отправ- лено достав- лено клик отмена подписки ожидание Рис. 10.13 Обновленная архитектура Если собрать все воедино, получится обновленная архитектура системы уведомлений, показанная на рис. 10.14. По сравнению с предыдущей архитектурой здесь появилось много новых компонентов.

Серверы уведомлений снабжены еще двумя важными функция­ ми — аутентификацией и ограничением трафика.

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

Шаблоны позволяют сделать процесс создания уведомлений со­ гласованным и эффективным.

Проектирование системы уведомлений      181 устройство параметры пользовательские данные БД Push-уведомления iOS Рабочие узлы Сервис N повторить в случае ошибки Аутентификация Ограничение трафика Серверы уведомлений Журнал уведомлений iOS APNs Аналитический сервис ожидание отправки отслеживание щелчков Шаблон уведомлений КЭШ КЭШ КЭШ отправлено Рис. 10.14

Наконец, были добавлены механизмы мониторинга и отслежива­ ния для проверки работоспособности системы и ее дальнейшего улучшения. ШАГ 4: ПОДВЕДЕНИЕ ИТОГОВ Уведомления позволяют оперативно доставлять важную информа­ цию, что делает их незаменимыми. Это может быть push-уведомление о ­вашем любимом фильме Netflix, электронное письмо о скидках на новые продукты или сообщение с подтверждением оплаты в онлайн- магазине. В этой главе мы обсудили проектирование масштабируемой системы уведомлений с поддержкой нескольких форматов: push-уведомлений, SMS-сообщений и электронных писем. Для разделения компонентов системы использовалась очередь сообщений. Определившись с общей архитектурой, мы подробно рассмотрели до­ полнительные компоненты и оптимизации.

182      ГЛАВА 10

Надежность. Мы предложили надежный механизм повторных вы­ зовов для минимизации частоты сбоев.

Безопасность. Чтобы уведомления могли отправлять только про­ веренные клиенты, мы использовали пару AppKey/appSecret.

Отслеживание и мониторинг. Эти механизмы могут быть реали­ зованы на любом этапе процесса отправки уведомлений для полу­ чения полезной статистики.

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

Ограничение трафика. Пользователи будут признательны, если уведомления не будут сыпаться на них ежеминутно. Поздравляем, вы проделали длинный путь и можете собой гордиться. Отличная работа! СПРАВОЧНЫЕ МАТЕРИАЛЫ [1]  Twilio SMS: https://www.twilio.com/sms [2]  Nexmo SMS: https://www.nexmo.com/products/sms [3]  Sendgrid: https://sendgrid.com/ [4]  Mailchimp: https://mailchimp.com/ [5]  You Cannot Have Exactly-Once Delivery: https://bravenewgeek.com/you- cannot-have-exactly-once-delivery/ [6]  Security in Push Notifications: https://cloud.ibm.com/docs/services/mobilepus h?topic=mobilepushnotification-security-in-push-notifications [7]  Key metrics forRabbitMQ: www.datadoghq.com/blog/rabbitmq-monitoring