Архитектура отправки пуш-уведомлений

Представляем вам очередную расшифровку с VK Tech Talks | Backend. В этот раз совместно с Ильшатом Шакировым разбёремся в архитектуре отправки пуш-уведомлений.

Начнём с того, что вообще такое пуш. Пуш — это всплывающие окна на мобильном устройстве, которые нужны для мгновенного уведомления пользователя о некотором событии.

Существует три типа пушей на платформе ВКонтакте:

  1. События (лайвы, посты, лайки, etc.);
  2. Мессенджер (сообщения);
  3. VOIP-пуши (уведомления для звонков внутри ВКонтакте).

Немного статистики:

Архитектура отправки пуш-уведомлений, image #1

Рассмотрим, как работает почти любая система пуш-уведомлений.

Всё начинается с пользователя. Пользователь листает приложение, которое так или иначе достаёт push-токен (строка, однозначно идентифицирующая устройство пользователя и приложения). Этот push-токен отправляется в бэкенд VK на хранение. При возникновении какого-либо события он вместе с содержание уведомления отправляется в push-провайдер (сервер для отправки пуш-уведомлений). Задача push-провайдера — доставить push-уведомление до пользователя.

Архитектура отправки пуш-уведомлений, image #2

Очевидно, что контролироваться может лишь эта часть, поэтому о ней и пойдёт речь далее.

Архитектура отправки пуш-уведомлений, image #3

Рассмотрим то, как мы будем сохранять push-токены пользователей.

Архитектура отправки пуш-уведомлений, image #4

Сделаем небольшое отступление и поговорим об API VK. Если вы хотите создать мобильное приложение, которое будет использовать все возможности платформы API, то вам необходимо зарегистрировать ваше приложение на нашей платформе. После чего вы получите особый токен, который будет использоваться для «похода» в нашей API.

Архитектура отправки пуш-уведомлений, image #5
Архитектура отправки пуш-уведомлений, image #6
1 of 2

Посмотрим на то, что мы храним о каждом устройстве пользователя:

Архитектура отправки пуш-уведомлений, image #7

Что может случиться и какие пути решения?

  1. Могут измениться параметры устройства.
    В обработчике API-метода учитываем одинаковые токены/device_id и создаем/обновляем устройства пользователя.
  2. Пользователь может удалить приложение.
    Правильно обрабатываем ошибки от push-провайдера, удаляя «протухшие» устройства пользователя.
  3. Пользователь может не пользоваться телефоном.
    Обновляем и следим за update_time устройства, своевременно удаляя его.
  4. На устройстве может авторизоваться другой пользователь.
    Храним обратный индекс token -> user и подчищаем «чужие» устройства.

Мы научились сохранять данные о пользователе. Далее необходимо сформировать пуш.

Архитектура отправки пуш-уведомлений, image #8

Подытожим:

  1. Уведомления делятся по типам msg, chat, new_post, like, etc.
  2. Каждому типу пуша — свой обработчик.
  3. На вход обработчику — устройства пользователя и данные уведомления.
  4. На выходе — N задач (по количеству устройств) на отправку пуша .

Поговорим о некоторых проблемах, которые мы решили.

Раньше был старый формат пушей, который заключался в индивидуальной отрисовке пуша для каждой платформы.

Архитектура отправки пуш-уведомлений, image #9
Архитектура отправки пуш-уведомлений, image #10
1 of 2

Пришло время для нового единого формата пушей:

  1. Выделение общих полей всех уведомлений;
  2. Построение на их основе уведомления для каждой платформы;
  3. Унификация работы клиентов с новым форматом пуш-уведомлений.
Архитектура отправки пуш-уведомлений, image #11

Посмотрим на структуру задачи, получаемую с обработчиков. Поделим её на две части: поля самой задачи и поля самого уведомления.

Архитектура отправки пуш-уведомлений, image #12
Архитектура отправки пуш-уведомлений, image #13

Сбор статистики с клиентов про пуши:

  1. Поле stat: “time_sent=123&log_id=234”;
  2. Собираются все действия с пушами: получение пуша, тап по пушу, нажатие на кнопки быстрых действий, скрытие пуша;
  3. Измеряется время доставки.

Поговорим про «пушилку», которая достаёт и обрабатывает сообщения с брокера.

  1. Демон на Go;
  2. 0,02 сек. на обработку одного пуша;
  3. Умеет отправлять в 6 пуш-провайдеров:
    ▪ Apple Push Notification Service (APNS)
    ▪ Google Cloud Messaging (GCM)
    ▪ Firebase Cloud Messaging (FCM)
    ▪ Browser
    ▪ Microsoft Push Notification Service (MPNS)
    ▪ Windows Notification Services (WNS)

Рассмотрим архитектуру самой пушилки:

Архитектура отправки пуш-уведомлений, image #14
Архитектура отправки пуш-уведомлений, image #15
1 of 2

Что умеет пушилка? В какие пуш-провайдеры какие пуши отправляются?

Архитектура отправки пуш-уведомлений, image #16

Не так давно мы узнали, что GCM/FCM поддерживают HTTP/2.

Окунёмся в историю. Раньше у Apple был свой бинарный протокол поверх TSP, который был достаточно неудобен.

Архитектура отправки пуш-уведомлений, image #17

Время шло, Go обновлялся и у HTTP/2 убрали некоторые проблемы. Мы решили обновиться.

Архитектура отправки пуш-уведомлений, image #18

Ночью всё прошло хорошо, но ближе к вечеру в наших Google-провайдерах максимальное время обработки пуша «улетела в полку». На графике это примерно 70 секунд, что равно нашим выставленным в коде тайм-аутам. Очевидно, что наши запросы просто отваливались по тайм-ауту.

Архитектура отправки пуш-уведомлений, image #19

Начали разбираться с этой проблемой. Залезли в процесс и увидели, что очень много времени тратится внутри реализации HTTP/2 в Go, что странно, потому что мы не писали никакой специальной поддержки для HTTP/2.

Стали копать ещё глубже.

Архитектура отправки пуш-уведомлений, image #20
Архитектура отправки пуш-уведомлений, image #21
1 of 2

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

Посмотрим на то, что мы мониторим и логируем, чтобы смотреть на то, как работают наши сервисы:

Архитектура отправки пуш-уведомлений, image #22
Архитектура отправки пуш-уведомлений, image #23

Подытожим что такое сервис-пушилки:

Архитектура отправки пуш-уведомлений, image #24

На этом доклад подходит к концу. Полное видео трансляции вы можете посмотреть ниже:

Архитектура отправки пуш-уведомлений, image #25
The Brown Room — независимое интернет-издание
о социальных сетях и технологиях

Автор: Сергей Котов
Корректор: Арсений Метелёв
Слайды и статистика: Ильшат Шакиров / ВКонтакте

904 views·3 shares
904 views