Шина событий
Когда происходит что-то, о чём стоит знать, панель создаёт событие и доставляет его каждому подписчику, который его запросил: вебхукам, дополнениям, чатам Telegram и адресам электронной почты. Эта страница объясняет, как выполняется доставка и на что может полагаться получатель. Список событий и их содержимого — в Каталог событий; настройка вебхука — в Вебхуки и события.
Выберите блок, чтобы прочитать, что в нём происходит.
События сообщают об изменениях
Событие говорит, что что-то изменилось: учётная запись исчерпала квоту, узел перестал отвечать, администратор вошёл с нового адреса, резервная копия готова. О длящемся состоянии сообщается один раз, когда оно начинается, и ещё раз, когда оно заканчивается, если это имеет смысл (диск узла заполняется, затем освобождается). Просто выключенный узел не создаёт событие при каждом heartbeat.
Предупреждения, которые должны пережить перезапуск, например предупреждение о сроке учётной записи или состояние дополнения, запоминаются в базе данных, поэтому перезапуск панели ни одно из них не повторяет. Несколько состояний, которые оцениваются по таймеру, например превышение лимита реселлером, запоминаются в памяти, и перезапуск может повторить каждое из них один раз.
Четыре семейства
Первое слово в имени события говорит, о чём оно, и это решает, кто может его слышать:
| Семейство | О чём | Примеры |
|---|---|---|
user.* | одна учётная запись; всегда называет администратора-владельца | user.quota_reached, user.expiring, user.first_fetch |
node.* | узел | node.disconnected, node.disk_high, node.rejections_high |
admin.* | учётная запись оператора | admin.login_new_ip, admin.resale_cap_reached |
panel.* | сама установка; никогда не называет учётную запись | panel.backup_failed, panel.cert_expiring, panel.addon_unhealthy |
Так как каждое событие user.* называет владельца, уведомление может уйти реселлеру, чей это клиент. Событие panel.* никогда не доходит до подписчика, привязанного к реселлеру.
Outbox
Создание события — одна транзакция базы данных:
- Событие один раз записывается в outbox.
- Для каждого включённого подписчика, чей фильтр событий его хочет и чей владелец может его видеть, рядом записывается одна строка доставки.
Если событие не нужно ни одному подписчику, не записывается ничего, поэтому у установки без подписчиков таблица остаётся пустой. Так как событие и его доставки записываются вместе, событие никогда не бывает доставлено наполовину: либо у каждого подписчика ждёт его доставка, либо ни у кого.
События и доставки хранятся в течение срока хранения событий, по умолчанию 7 дней и не больше 90, и входят в каждую резервную копию.
Доставка и повторы
Фоновый обработчик в панели отправляет доставки, которым пора:
- По порядку для каждого подписчика. Доставки каждого подписчика идут одна за другой, поэтому получатель видит события в том порядке, в котором они произошли. Разные подписчики друг друга не ждут.
- Неудача повторяется после задержки, которая каждый раз удваивается, начиная с 30 секунд и не больше часа, с небольшой случайностью, чтобы повторы не приходили одновременно.
- После 10 попыток доставка считается мёртвой. Она остаётся в списке с последним ответом, и Отправить снова повторяет её вручную.
- Подписчик отключается, только если его неудачи одновременно идут длинной серией и старше суток. Получатель, который час был недоступен и на котором повторяется накопившаяся очередь, не отключается. Повторное включение начинает счёт заново.
- Перенаправления не выполняются.
Отправить тестовое событие сразу отправляет panel.ping и показывает ответ получателя.
Конверт
Вебхук получает POST с телом JSON:
{
"v": 1,
"id": 1842,
"event": "user.quota_reached",
"time": 1791711000,
"data": { "userId": 57, "name": "ali", "adminId": 3 },
"recipients": [3]
}id — собственный идентификатор события, одинаковый для каждого подписчика и каждого повтора. time — в секундах Unix. recipients, если есть, перечисляет администраторов, которых касается событие.
Вместе с ним приходят три заголовка:
| Заголовок | Что несёт |
|---|---|
X-Nexora-Event | имя события |
X-Nexora-Delivery | идентификатор доставки; повтор его сохраняет, поэтому получатель отбрасывает повторы по этому идентификатору |
X-Nexora-Signature | метку времени и HMAC-SHA256 от метки времени и тела, сделанный секретом подписчика |
Получатель проверяет подпись секретом, который ему показали один раз, при создании подписчика. Восстановление из резервной копии возвращает и таблицу доставок, поэтому после него идентификаторы доставок могут повторяться: получатель, который хранит идентификаторы между восстановлениями, должен начать заново при panel.restore_applied.
Тонкое содержимое
Содержимое несёт идентификаторы, имена и то, что изменилось, но никогда не учётные данные: ни пароля, ни ключа, ни токена подписки, ни ссылки. Получатель, которому нужно больше, читает это через API своим токеном, в пределах своих прав.
- Массовые действия и пакетное создание создают одно сводное событие, а не по одному на учётную запись.
panel.settings_changedназывает настройку, но никогда её значение.
Кто куда может подписаться
- Вебхук, который вы добавляете вручную, не может указывать на собственную сеть панели: loopback, частные и подобные адреса отклоняются, когда панель подключается, во что бы ни разрешалось имя.
- Вебхук дополнения принадлежит его API-токену. Он слышит только события, которые вы одобрили по его манифесту, может обращаться к дополнению, работающему рядом с панелью в частной сети, и молчит, пока дополнение приостановлено.
Каналы для людей
Чаты Telegram и адреса электронной почты — это люди, а не программы. Шина передаёт каждую доставку отправителю Telegram или почты вместо POST, с теми же повторами, и сначала её фильтрует:
- Чат или адрес слышит только то, что может читать роль его учётной записи. Чат реселлера слышит о его собственных клиентах и ни о чём другом.
- Выключенный сервис ничего не доставляет.
- Адрес электронной почты должен быть подтверждён, прежде чем на него что-либо отправят.
Шина как сигнал состояния
Доставка, которая так и не дошла, ничего не сообщает своему получателю. Поэтому панель всегда экспортирует на своём эндпоинте метрик число ожидающих, доставленных и мёртвых доставок, чтобы могло сработать оповещение о мёртвых доставках; см. Мониторинг и метрики.
