Xiva — это многоканальный транспорт для быстрых нотификаций между
подписчиками и отправителями.
Присылайте вопросы и пожелания через форму
и вступайте в наш клуб
в этушке, чтобы следить за будущими анонсами.
По срочным вопросам призывайте дежурного через
YaIncBot командой /onduty xiva.
Дальнейшая эскалация:
nordsturm@,
3y3k0@.
30 млн. WebSocket подписок онлайн |
1 млрд. мобильных и браузерных подписок |
8 млрд. нотификаций в сутки |
push.yandex.<TLD> — продакшн
push-sandbox.yandex.ru — тестинг, живет в отдельной сети
push.yandex-team.ru — корпоративная инсталляция
Окружения полностью изолированы, за исключением сертификатов мобильных приложений.
Xiva построена по классической модели publish-subscribe.
Сервис — это аккаунт в Xiva с изолированной аудиторией и правами. Подробнее о разграничении прав доступа см. ниже в разделе "Авторизация".
Подписка — это любое устройство или приложение, в которое можно отправлять уведомления по одному из поддерживаемых каналов доставки.
Подписки делятся на четыре категории:
Мобильные пуши работают через проприетарные протоколы производителей и позволяют отправлять уведомления даже в закрытое приложение, экономят заряд батареи и лучше работают в условиях плохого интернет-соединения.
Используйте WebSocket, когда минимальные задержки и надежность имеют решающее значение. Если вы не знаете, какая технология лучше подходит для ваших задач — напишите нам, мы поделимся своим опытом и расскажем о существующих подходах.
Субъектами авторизации в Xiva являются бэкенды Яндекса, желающие отправлять пуши пользователям/подписывать пользователей на пуши (кроме подписки по websocket и подписки мобильных приложений, подробнее см. документацию на эти методы). У бэкенда может быть либо право отправлять пуши в некотором сервисе, либо подписывать пользователей в этом сервисе на пуши, либо и то, и другое. Проверять авторизацию бэкенда Xiva умеет одним из двух способов:
В этом случае право на отправку/подписку выдаётся некоторому TVM-приложению, связанному с авторизующимся бэкендом. Для управления правами на отправку/подписку Xiva использует специальную систему в IDM. Роли в этой системе имеют структуру сервис/окружение/тип, где тип — publisher, если нужно отправлять пуши, либо subscriber, если нужно подписываться на пуши. Подробнее о получении ролей можно прочитать в инструкции по настройке доступа в разделе "Быстрый старт".
Xiva принимает service-тикеты в стандартном заголовке X-Ya-Service-Ticket. Вместе с тикетом необходимо передать через URL-параметр service имя сервиса, в котором будет происходить авторизация.
Если вы только начинаете использовать Xiva — пожалуйста, не используйте этот способ авторизации. Мы рекомендуем использовать TVM service-тикеты, инструкция по настройке есть в разделе "Быстрый старт".
С каждым сервисом связан набор буквенно-цифровых секретов — Xiva-токенов. Пожалуйста, не публикуйте их в открытых источниках, репозиториях с кодом, чатах и трекере. Токены бывают двух видов - отправки (send-токены) и подписки (listen-токены). Send-токены разрешают отправку пушей пользователям в сервисе, в котором выписаны. Listen-токены разрешают управление подписками на пуши (создать/удалить/получить список) в сервисе, в котором выписаны.
Чтобы авторизоваться Xiva-токеном, передайте вместе с запросом заголовок Authorization: Xiva token.
Управление токенами происходит в разделе "Аккаунты". Можно выписывать новые токены/отзывать старые или скомпрометированные.
Одним из существенных признаков подписки является идентификатор пользователя. Это позволяет отправлять нотификации по идентификатору пользователя, а также одним запросом отправлять сразу во все подписки.
Какие бывают пользователи:
Особый случай — топики. Это именованная группа подписок разных пользователей. Идентификатором топика служит строка, выбираемая сервисом.
Топики в Xiva не нужно особым образом заводить или регистрировать. Чтобы завести топик, достаточно подписать на него хотя бы одного пользователя.
При подписке нужно указать идентификатор пользователя — это позволит знать, какие пользователи подписаны на топик. Для паспортных идентификаторов пользователей также доступно автоматическое удаление подписки при отзыве авторизации.
Важно: топики в Xiva не рассчитаны на большое количество подписчиков (в отличие от топиков в FCM), ориентируйтесь на число 100 подписок в одном топике. Если вам нужно отправлять уведомления на всю аудиторию, напишите нам — мы поможем.
Нотификации, уведомления или пуши — сообщения, доставляемые подписчикам. Стандартным форматом нотификаций является JSON. В WebSocket подписки можно также отправлять бинарные данные.
Мобильные пуши мы разделяем на скрытые (они же silent- или data-пуши) и яркие (bright, системные). Строго говоря, второе название не используется внешними пуш-сервисами, оно введено нами для удобства. Отличие между этими пушами в том, что первые доставляются приложению в фоне, а вторые отрисовываются системой и не обязательно доходят до приложения. Например, background update notification в APNS или data message в FCM — это silent-пуш в Xiva.
Наш собственный транспорт, в котором мы контролируем весь путь доставки нотификаций и можем получать подтверждения от клиентов.
В одном соединении можно подписаться на несколько пользователей и сервисов.
Клиент может не только получать нотификации по WebSocket, но и обмениваться данными со своим бэкендом и получать от него ответы. Эта возможность называется reverse proxy, более детально с ней можно ознакомиться в её спецификации.
Соединения терминируются через L3 балансеры без промежуточных балансировщиков. Сервер использует TCP KeepAlive для обнаружения и удаления утерянных соединений. На клиенте стоит ориентироваться на служебный пуш ping. Подробнее про это можно узнать в описании метода подписки. Мы не используем протокольный WebSocket ping (но отвечаем на него), потому что большинство наших клиентов не смогут его получить.
Мобильные подписки идентифицируются парой user (либо topic) и UUID. Если повторно подписаться с теми же user и UUID, то произойдет обновление существующей подписки - перезапишутся push-токен, client, фильтры и другие параметры.
Переустановка приложения, перевыпуск push-токенов, сетевые проблемы и ряд других ситуаций могут привести к появлению нескольких подписок, через которые можно отправить нотификацию в одно приложение. Это может приводить к дублированию уведомлений на экране телефона пользователя.
Транспорт обеспечивает обнаружение и автоматическое удаление дубликатов мобильных подписок по двум наборам ключей:
Важно: в некоторых случаях на устройстве меняются одновременно все атрибуты: и UUID, и DeviceID, и push-токен. Это случается хотя и редко, но регулярно. При этом обе подписки длительное время работают. В настоящее время нет хорошего способа это исправить. По жалобе пользователя можно вручную удалить лишние подписки в разделе "Инструменты".
Как правило в Андроид высокая доставляемость data-пушей, поэтому чаще всего для этой платформы используют именно их. Обработка пушей приложением позволяет не показывать пуш два раза, если все-таки подписка задублировалась. В iOS у silent пушей доставляемость крайне низкая, поэтому туда обычно отправляют как bright. Из этого следует одна важная особенность: при описанном выше сценарии, когда на устройстве меняются все идентификаторы, дедублицировать пуши не получится. Частично побороть проблему можно, передавая в collapse-id уникальный идетификатор пуша.
Внутренняя сеть не считается безопасной, используйте HTTPS и WSS. Убедитесь, что токены и куки из запросов не попадают в логи.
Рекомендуем сохранять в лог заголовки Y-Context и TransitID (если есть) из ответа сервера, это поможет быстрее диагностировать проблемы. При ошибках применяйте прогрессивные ретраи.
При разработке клиентов придерживайтесь принципов защитного программирования. Закладывайтесь на то, что могут приходить неизвестные приложению нотификации, нотификации в любом формате, с новыми или отсутствующими полями.
Учитывайте, что сервер в произвольный момент времени может сбросить WebSocket соединение по техническим причинам. В этом случае следует переподключиться.
По возможности передавайте следующие HTTP заголовки в ваших запросах:
Не используйте значения таймаутов меньше секунды, даже если пытаетесь хеджировать запросы. Рекомендуемые значения — 1-2 секунды для обычных запросов и десятки секунд — для пакетных (батчевых). Реальные тайминги существенно ниже, однако в условиях инцидента они могут вырасти и ухудшить доставку пушей вашего сервиса.
Текущие ограничения нагрузки:
Xiva хорошо масштабируется горизонтально и выдерживает большие нагрузки от всех сервисов Яндекса. Показатели, в которые мы целимся: 99,99% доступности и 99 перцентиль времен ответов до 500ms (за исключением пакетной и широковещательной отправки).
Метрики в реальном времени можно посмотреть тут. Срез по вашему сервису можно получить там же, указав параметр service в поле ввода.
Xiva отгружает свои логи в YT: продакшн, тестинг. Из лога можно получить историю подписок и отписок, статусы отправки каждой нотификации. Уникальным идентификатором нотифкации в системе является TransitID. Пример YQL запроса можно посмотреть тут.
основные колонки
Колонка | Описание |
uid | user или topic. |
event | тип события из нотификации. |
transit_id | уникальный идентификатор нотификации. |
platform | мобильная платформа. |
client | название клиента. |
subscription_id | идентификатор подписки. |
time_elapsed | итоговое время обработки нотификации в миллисекундах. |
status | статус отправки:
conveyed - успешно отправлено convey failed - ошибка отправки dropped - подписка удалена, т.к. внешний пуш-сервис её инвалидировал skip - нотификация отклонена фильтром expired - истек TTL доставки ignored - нотификация отброшена из-за некорректного формата содержимого или правил переупаковки В логе могут присутствовать и другие события. Они используются исключительно в служебных целях. |
reason | дополнительная информация о причине неотправки, может отсутствовать. |
Внешние пуш-сервисы не предоставляют информации о статусе доставки, поэтому для сбора статистики доставки необходимо сделать логирование в мобильном приложении. Для этого можно использовать метод reportEvent AppMetrica SDK. Эти логи тоже запишутся в YT, где их можно будет связать с логами отправки.
Примеры событий, которые логирует Яндекс.Почта: