Real-Time Backend

Push Notifications архитектура

WhatsApp отправляет миллиарды уведомлений в день на iOS и Android. Как построить надёжный pipeline через Apple APNs и Google FCM?

  • **Airbnb Notification Service** - 50M уведомлений/день через Kafka pipeline, FCM batch API по 500 токенов за запрос снижает HTTP overhead в 100x, автоматическая очистка невалидных токенов
  • **WhatsApp** использует priority: 'normal' для большинства уведомлений (экономия батареи), 'high' только для звонков - это требование APNs для VoIP пушей с немедленным пробуждением
  • **Duolingo** - ежемесячная очистка 30-40% мёртвых токенов через APNs Feedback Service, снижение затрат на рассылку на 35% и ускорение батчевой отправки

APNs (Apple Push Notification service)

**APNs** - сервис Apple для доставки push-уведомлений на iOS, macOS, watchOS и tvOS устройства. Архитектура: сервер приложения -> APNs -> устройство. APNs держит постоянное TLS соединение с каждым устройством (persistent connection через Apple Data Centers) и доставляет пуш за миллисекунды, когда устройство онлайн.

Аутентификация на APNs: два варианта - **certificate-based** (p12/PEM файл, привязан к одному bundle ID, истекает через год) и **token-based** (JWT с ES256 подписью, один .p8 ключ для всех app bundle ID, не истекает). Все крупные компании используют token-based: один ключ управляет Uber, Uber Eats, Uber Freight на одном Apple Developer аккаунте.

APNs доставляет 5+ миллиардов уведомлений в день. Гарантия доставки: если устройство офлайн - APNs хранит последнее уведомление per bundle ID до 30 дней (или по TTL из `apns-expiration` header). При `apns-collapse-id` несколько уведомлений схлопываются в одно.

Чем token-based аутентификация на APNs лучше certificate-based?

FCM (Firebase Cloud Messaging)

**FCM** - сервис Google для push-уведомлений на Android (через GCM legacy и FCM v1 API), Web (через Service Workers и Web Push Protocol) и iOS (FCM проксирует через APNs). Единый API для всех платформ - это главное преимущество перед прямой работой с APNs+Web Push отдельно.

FCM v1 API (заменил legacy в 2023) использует OAuth 2.0 с service account JSON. Payload разделён на **notification** (отображается системой автоматически) и **data** (обрабатывается приложением). `notification` объект разный для Android, iOS и Web - FCM нормализует различия. При офлайн устройстве FCM хранит уведомления до 4 недель.

WhatsApp обрабатывает 100+ млрд сообщений в день, из которых значительная часть триггерит push через FCM/APNs. Для снижения стоимости они используют priority: 'normal' для большинства уведомлений (батарейный режим) и 'high' только для входящих звонков.

Как FCM доставляет push-уведомления на iOS?

Push Pipeline

**Push pipeline** - цепочка от бизнес-события до уведомления на устройстве. Компоненты: event source (действие пользователя или системы) -> message queue (Kafka, RabbitMQ) -> notification service (обогащение, таргетирование) -> delivery service (FCM/APNs клиент) -> платформа (APNs/FCM) -> устройство.

Очередь между событием и отправкой критична для масштаба. Без неё при spike нагрузки (запуск акции на 10M пользователей) сервис упадёт от одновременных запросов к APNs/FCM. С Kafka: события пишутся моментально, N воркеров читают и отправляют с ограниченной скоростью. Instagram использует именно этот паттерн для массовых нотификаций.

Airbnb публиковала архитектуру: Notification Service обрабатывает 50M уведомлений в день через Kafka. Воркеры потребляют из топика и батчат запросы к FCM (до 500 токенов в одном запросе через FCM batch API) - это снижает HTTP overhead в 100x.

Зачем помещать уведомления в Kafka перед отправкой, а не слать напрямую в FCM из обработчика события?

Push Delivery и Надёжность

APNs и FCM возвращают коды ответа, которые определяют дальнейшую логику. **410 Gone** от APNs или `UNREGISTERED` от FCM означает: токен невалиден, устройство было переустановлено приложение или сброшено. Такой токен надо немедленно удалить из БД - иначе копятся мёртвые токены и растут расходы.

**Delivery receipt** - APNs и FCM не гарантируют доставку до устройства (только до своих серверов). Для critical уведомлений (звонки, платежи) используют дополнительный канал: приложение при открытии подтверждает получение через API, сервер ставит таймер и при отсутствии подтверждения отправляет SMS или email как fallback.

Duolingo сообщает: 30-40% токенов в production БД - невалидные (устройства сброшены, приложения переустановлены). Ежемесячная очистка через APNs Feedback Service снижает затраты на отправку на 35% и улучшает скорость батчевой рассылки.

Push notification = гарантированная доставка сообщения пользователю

Push notification = best-effort доставка: APNs/FCM гарантируют приём запроса, но не показ на экране - устройство офлайн, DND, невалидный токен, системные лимиты

Критические уведомления (банковские транзакции, экстренные оповещения) требуют application-level delivery confirmation + fallback через SMS. Это отдельный слой поверх push.

Приложение отправляет критическое уведомление о платеже. APNs вернул 200 OK. Можно ли считать что пользователь увидел уведомление?

Итоги

  • **APNs** (iOS) и **FCM** (Android/Web) - два обязательных канала; FCM проксирует на APNs для iOS, позволяя использовать единый API
  • **Push pipeline**: событие -> Kafka queue -> notification worker (обогащение) -> FCM/APNs -> устройство; очередь критична для spike нагрузки
  • **Delivery != показ**: APNs 200 OK = принято, не показано; критические уведомления требуют application-level receipt + SMS fallback; мёртвые токены = деньги впустую

Связанные темы

Push notifications - часть broader системы уведомлений:

  • In-App Notifications — Push доставляет уведомление когда приложение закрыто; in-app система показывает его внутри приложения в реальном времени
  • Message Queues (Kafka) — Kafka буферизует events перед отправкой - защита от spike нагрузки при массовых рассылках
  • WebSocket — In-app real-time уведомления идут через WebSocket; push - fallback когда приложение закрыто

Вопросы для размышления

  • Приложение хранит device tokens в PostgreSQL. После 3 месяцев в проде токенов накопилось 2M, из которых ~40% невалидны. Как построить автоматизированную очистку через APNs Feedback Service?
  • Нужно отправить маркетинговое уведомление 10M пользователей за 15 минут до старта акции. Как рассчитать количество воркеров при ограничении FCM 600 запросов/сек и batch size 500 токенов?
  • iOS пользователь включил Focus Mode. Уведомление отправлено, APNs вернул 200. Пользователь не видит уведомления. Как приложение должно обработать эту ситуацию?

Связанные уроки

  • sd-09-message-queue
Push Notifications архитектура

0

1

Войти