事件总线
当有值得知道的事情发生时,面板会发出一个事件,并投递给每个订阅了它的订阅者:Webhook、插件、Telegram 聊天和电子邮件地址。本页说明投递是如何完成的,以及接收方可以依赖什么。事件列表及其载荷见 事件目录;设置 Webhook 见 Webhook 与事件。
点击任意方框,查看那里发生了什么。
事件报告变化
事件表示某样东西发生了变化:某个账户达到了额度、某个节点停止应答、某位管理员从新地址登录、一次备份完成。持续存在的状态只在开始时报告一次,在合适的情况下结束时再报告一次(节点磁盘快满,然后恢复)。只是被停用的节点不会在每次心跳时都发出事件。
必须在重启后保留的警告(例如账户的到期警告或插件的健康状态)记录在数据库中,所以重启面板不会重复它们中的任何一个。少数按定时器判断的状态(例如代理商超出配额)记录在内存中,重启后每个可能重复一次。
四个类别
事件名称的第一个词说明它涉及什么,这也决定了谁可以收到它:
| 类别 | 涉及 | 示例 |
|---|---|---|
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.* 事件永远不会到达绑定在代理商身上的订阅者。
发件箱
发出一个事件是一个数据库事务:
- 事件被写入发件箱一次。
- 对每个已启用、事件过滤器需要它、且其所有者可以看到它的订阅者,在旁边写入一行投递记录。
没有订阅者需要某个事件时,什么都不写,所以没有订阅者的安装会保持一张空表。由于事件和它的投递是一起写入的,事件永远不会只投递了一半:要么每个订阅者都有待投递的记录,要么都没有。
事件和投递按事件保留期保存,默认 7 天,最长 90 天,并且是每份备份的一部分。
投递与重试
面板中的一个后台工作进程负责发送到期的投递:
- 每个订阅者按顺序。 每个订阅者的投递一个接一个地发送,所以接收方看到事件的顺序与发生的顺序一致。不同的订阅者互不等待。
- 失败会重试,延迟每次翻倍,从 30 秒开始,上限一小时,并带有少量随机性,避免重试同时到达。
- 10 次尝试后投递即作废。 它会连同最后一次应答保留在列表中,重新发送 可手动重试。
- 订阅者只有在失败既连续很长、又超过一天时才会被停用。 宕机一小时、积压的投递正在对它重试的接收方不会被停用。重新启用它会让计数从头开始。
- 不跟随重定向。
发送测试事件 会立即发送 panel.ping 并显示接收方的应答。
信封
Webhook 收到一个带 JSON 正文的 POST:
{
"v": 1,
"id": 1842,
"event": "user.quota_reached",
"time": 1791711000,
"data": { "userId": 57, "name": "ali", "adminId": 3 },
"recipients": [3]
}id 是事件自己的 id,对每个订阅者、每次重试都相同。time 以 Unix 秒为单位。recipients 出现时,列出该事件涉及的管理员。
它带有三个头部:
| 头部 | 携带内容 |
|---|---|
X-Nexora-Event | 事件名称 |
X-Nexora-Delivery | 投递 id;重试时会重复,所以接收方按这个 id 丢弃重复项 |
X-Nexora-Signature | 一个时间戳,以及用订阅者密钥对时间戳和正文计算的 HMAC-SHA256 |
接收方用创建订阅者时只显示过一次的密钥校验签名。从备份恢复时,投递表也会一起恢复,所以恢复后投递 id 可能重复:跨恢复保存 id 的接收方应在收到 panel.restore_applied 时从头开始。
精简的载荷
载荷携带 id、名称和变化的内容,从不携带凭据:没有密码、密钥、订阅令牌或链接。需要更多信息的接收方用自己的令牌、在自己的权限下从 API 读取。
- 批量操作和批量创建只发出一个汇总事件,而不是每个账户一个。
panel.settings_changed写明设置项,从不写明它的值。
谁可以在哪里订阅
- 你手动添加的 Webhook 不能指向面板自己的网络:无论名称解析到什么,面板连接时都会拒绝回环地址、私有地址及类似地址。
- 插件的 Webhook 属于它的 API 令牌。 它只收到你从其清单中批准的事件,可以访问在私有网络上与面板并排运行的插件,并在插件暂停期间保持静默。
面向人的渠道
Telegram 聊天和电子邮件地址是人,不是程序。总线把每次投递交给 Telegram 或电子邮件发送器,而不是发 POST,重试方式相同,并先进行过滤:
- 聊天或地址只收到其账户角色可以读取的内容。 代理商的聊天只收到有关自己客户的消息,别无其他。
- 已关闭的服务什么都不投递。
- 电子邮件地址必须先确认,才会向它发送任何内容。
总线作为健康信号
一次永远到不了的投递,对接收方什么也说明不了。因此面板始终在其指标端点上导出待投递、已投递和已作废投递的数量,以便针对作废投递的告警能够触发;参见 监控与指标。
