Skip to content

后台任务与多实例协调 ​

除了处理 HTTP 请求,Sub2API 还运行多种周期任务和 worker。它们决定 token、订阅、统计、备份和异步任务能否长期保持健康。

主要后台任务 ​

任务作用
Token Refresh提前刷新 OAuth token
Account Expiry到期账号自动暂停
Proxy Expiry到期代理切换或恢复
Subscription Expiry更新订阅状态和提醒
Payment Order Expiry对账、关闭超时订单
Usage Cleanup批量删除历史用量
Idempotency Cleanup清理过期幂等记录
Dashboard Aggregation生成仪表盘小时/日统计
Ops Metrics/Aggregation采集系统指标和预聚合
Ops Cleanup删除过期错误、指标和日志
Ops Alert Evaluator根据规则生成告警事件
Scheduled Reports生成周期运维报告
Scheduler Snapshot更新账号调度快照
Channel Monitor定时检测渠道模板与状态
Scheduled Account Test执行账号测试计划
Backup定时或手动数据库备份
Batch Image Worker消费图片任务、轮询和结算
Platform Quota Flusher批量回写用户平台配额

Leader Lock ​

多实例不能让每个副本都执行同一个全量任务。通用策略:

  1. 使用 Redis SET NX 获取带 owner 和 TTL 的 leader lock。
  2. 被其他实例持有时跳过本轮。
  3. Redis 出错时,部分任务回退 PostgreSQL advisory lock。
  4. 任务完成后 compare-and-delete 释放。
  5. 下一轮重新竞选,不永久绑定 leader。

TTL 必须大于任务最坏执行时间,否则锁执行中到期,另一个实例可能同时开始。

Heartbeat ​

Ops job heartbeat 用于区分:

  • 任务正常执行但本轮无数据。
  • 任务未被当前实例选为 leader。
  • 任务卡死或长时间没有运行。
  • 任务运行失败。

告警应根据计划周期设置阈值。例如每天一次的 cleanup 不能使用 5 分钟无心跳告警。

Token Refresh ​

周期刷新会扫描接近过期的 OAuth 账号,并且每个账号仍需要独立刷新锁。全局任务选主只能避免重复扫描,账号锁用于防止请求热路径与后台刷新并发。

监控:

  • refresh request/success/failure。
  • lock contention 和 wait time。
  • OAuth 401 cooldown。
  • refresh token rotation 后持久化失败。

过期任务 ​

账号、代理、订阅和订单的“过期”含义不同:

  • 账号:可以自动设为不可调度。
  • 代理:可能切换 fallback proxy,并保留原 proxy ID 供恢复。
  • 订阅:更新状态并发送提醒。
  • 支付订单:先尝试 reconcile,再标记过期。

这些任务不应通过数据库定时器替代,因为它们还涉及缓存、通知和外部平台查询。

聚合与清理 ​

直接在仪表盘扫描全部 usage_logs 会越来越慢。聚合任务生成小时、日表,清理任务按保留期删除原始或中间数据。

部署时要保证:

  • 聚合已经覆盖将要删除的原始数据。
  • cleanup 使用小批次,避免长事务和表膨胀。
  • PostgreSQL 有 autovacuum 和磁盘余量。
  • 任务失败有告警,不是静默跳过。

Batch Image Worker ​

批量图片任务包含 ready、delayed、active、inflight 和 lock 状态。Worker 需要处理:

  • 新任务消费。
  • 上游异步提交。
  • 延迟轮询。
  • worker 崩溃后的 stale active 恢复。
  • 余额冻结、结算和释放。
  • 输入输出保留与清理。

启用该功能后,Redis 队列和对象存储不再是可忽略的附属依赖。

Worker Pool 与应用退出 ​

用量、邮件、批量任务等 worker 在应用退出时需要 Stop/StopAndWait。部署平台要提供足够 termination grace period,让:

  1. 停止接受新请求。
  2. 取消周期任务。
  3. 等待关键用量任务完成。
  4. 释放数据库和 Redis 连接。

直接 SIGKILL 会中断尚未落库的内存任务。

多实例配置要求 ​

  • 所有副本使用相同 Redis 和 PostgreSQL。
  • 系统时间和时区一致。
  • leader lock key 不被不同环境共用。
  • staging 与 production 必须使用不同 Redis DB/前缀和数据库。
  • 每个实例有唯一 instance ID。
  • 总数据库连接池按实例数计算。

运维检查 ​

每天或通过告警观察:

  • job heartbeat 是否更新。
  • leader lock 是否长期不释放。
  • scheduler outbox lag/backlog。
  • usage worker waiting/dropped/sync fallback。
  • quota flusher dirty/readd/error。
  • cleanup 删除数量与耗时。
  • batch queue ready/delayed/active 数量。
  • token refresh 失败账号数量。

本文档用于帮助你理解、部署和运维 Sub2API。使用前请确认上游服务条款与当地法律要求。