简体中文
通知内部实现
面向实现渠道和投递工作任务的贡献者。运维配置见通知。
SMTP 所有权
邮件渠道会为连续消息复用 SMTP 连接。替换配置后会使用独立连接池;此前已接收的投递任务仍使用原渠道。禁用渠道或被优先级过滤的消息不会初始化 SMTP 传输。邮件仍立即发送:存储 JSON 中的旧 batch_window_secs 设置会被忽略,Rust EmailConfig 接口已移除此字段。
本地化渲染
每次投递尝试只读取一次服务端语言,并在使用相同有效语言的渠道间共享已渲染的 标题和正文。重试会重新获取语言快照。各渠道随后分别处理转义、邮件 MIME 内容和 Telegram 实体格式。
送达行为
外部渠道会对临时失败进行退避重试,并对反复失败的渠道使用熔断器。重试耗尽的送达会进入死信,通知事件则按配置保留周期留在事件历史中。
数据库渠道重载会一起发布渠道与订阅。只要数据库 ID 仍处于已加载状态,修改名称、目标、凭据或订阅都会保留该渠道的熔断历史。移除或禁用会结束这一代渠道,重新添加后使用新的熔断器。已接收的通知及其重试继续使用重载前选定的渠道实例。仓库读取失败会保留已加载的注册表。
这些机制只能减少临时丢失,不能构成端到端送达保证。应监控接收服务,在配置变更后重新测试渠道,并为严重事件设置第二目标。
Web Push 使用容量为 2,048 个事件的 FIFO 队列,正常运行时工作线程每批最多处理 64 个事件。队列满时丢弃最新到达的事件,对所有优先级(包括严重事件)采用相同策略。工作线程未启动、队列已关闭或服务关闭时也拒绝新的推送事件。notification_stats.web_push_dropped 计数器记录这些入队失败,并以限频警告日志提示。事件历史持久化与外部渠道送达独立继续,丢弃的推送不会自动重放。关闭时会在现有后台任务关闭预算内尝试发送已接收的事件,但成功入队不代表已送达。
队列与 Web Push 投递
普通渠道投递会串行处理队列准入;容量已满时移除最早的待投递通知,并取消其计划重试。 队列上限为零时不接受普通渠道投递,事件日志与 Web Push 仍独立运行。已开始的发送可在 通知被移除后完成。熔断期间不增加投递尝试次数;刚触发熔断的失败也会遵守重试冷却时间。
Web Push 发送成功后会清除持久化限流状态,包括首次 HTTP 请求即成功的情况。只有 SQLite 确认删除后才报告失效订阅已删除。正常及精简 JSON 负载均必须满足字节上限;元数据过大时 会在发送 HTTP 请求前返回错误。
后端通知接口
渠道注册与重载、源事件映射、投递与重试、Web Push 队列与工作任务分别由独立模块 负责。公开事件目录和本地化方法仍可通过 notification::events 访问。自定义 Rust 渠道可以继续实现 NotificationChannel::send;新增的可选 send_rendered 方法提供 RenderedEvent,便于复用共享的标题和正文。直接调用内置渠道与队列投递使用相同的 过滤和消息构建路径。默认 test 方法同样遵守正常投递的过滤规则。