Files
shaguabijia-app-server/deploy/daily-exchange.md
T
zhuzihao 8a2f72d366 feat(user): 昵称上限放宽到 20 字(与客户端/原型一致) (#63)
Co-authored-by: zzhyyyyy <2685922758@qq.com>
Reviewed-on: #63
Co-authored-by: zhuzihao <zhuzihao@wonderable.ai>
Co-committed-by: zhuzihao <zhuzihao@wonderable.ai>
2026-06-21 00:16:40 +08:00

3.8 KiB
Raw Permalink Blame History

0 点自动兑金币 定时任务 — 运维手册

对象:维护「每天 0 点把用户金币自动兑成现金」这套定时任务的同事。 🔒 服务器登录信息见私密交接清单,不入库。

现状(2026-06 起):已改为 App 进程内任务,不再需要 systemd timer

「0 点自动兑换」现由 App 进程内后台任务 app.core.daily_exchange_worker 负责:App 一起来就 每 10 分钟检查、跨过北京 0 点自动跑一轮(逐用户幂等、文件锁互斥、重启补跑当天遗漏)。无需再装 / 启用 daily-exchange.timer

  • 开关仍是 .envAUTO_EXCHANGE_ENABLED(false → worker 不启动);间隔由 AUTO_EXCHANGE_CHECK_INTERVAL_SEC(默认 600s=10min)控。
  • 下方 systemd timer / 脚本属遗留 + 手动应急:逻辑同一套且幂等,可手动 --once 补跑; 但不要再 enable timer 与进程内 worker 并存(虽幂等不会双兑,纯属多余)。

它是什么

客户端已删手动「兑金币」入口、改为「0 点自动兑现金(可能存在延迟)」,故服务端每天 0 点跑一轮: 把每个用户的金币按汇率 100 金币 = 1 分 兑成现金。

  • 到分全额:coin_amount = floor(余额 / 100) × 100,不足 1 分(<100 金币)的零头留到下次。
  • 复用 exchange_in 流水类型(手动兑入口已下线,不会混淆),用户在「现金明细」看到「金币兑换现金」。
  • 幂等:同一用户当天已有 exchange_in 流水则跳过 → timer 重触发 / 手动重跑当天不会重复兑。
  • 逻辑见 app/repositories/wallet.py::daily_auto_exchange,入口 scripts/daily_auto_exchange.py

文件

路径
脚本入口 scripts/daily_auto_exchange.py
核心逻辑 app/repositories/wallet.py::daily_auto_exchange
开关 .envAUTO_EXCHANGE_ENABLED(默认 true;false=脚本 no-op)
systemd 单元 deploy/daily-exchange.{service,timer}
运行锁 /tmp/daily_auto_exchange.lock(可用环境变量 DAILY_EXCHANGE_LOCK 覆盖)

(遗留 / 可选)systemd timer 部署 — 现已被进程内 worker 取代,正常无需执行

# ⚠️ 仅在你明确想用外部 timer 而非进程内 worker 时才做(并把 worker 关掉),否则跳过。
sudo cp deploy/daily-exchange.{service,timer} /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now daily-exchange.timer
systemctl list-timers daily-exchange.timer   # 确认下次触发时间

本机 Windows 开发(无 systemd)

直接手动跑:

.venv\Scripts\python -m scripts.daily_auto_exchange --once
# 本地循环调试(每小时一轮,幂等空跑无害):
.venv\Scripts\python -m scripts.daily_auto_exchange --loop --interval 3600

怎么看健康 / 手动跑一次

sudo systemctl start daily-exchange.service     # 立即手动跑一轮(不等 0 点)
journalctl -u daily-exchange -n 30 --no-pager   # 看日志:扫描/兑换/跳过/失败/累计兑入分

日志一行形如:自动兑完成 用时1.2s 扫描120 兑换88 已兑过跳过30 零头跳过2 失败0 累计兑入15600分

怎么关 / 临时停

  • 临时停(推荐):.envAUTO_EXCHANGE_ENABLED=false → 脚本 no-op,无需动 timer。
  • 停 timer:sudo systemctl disable --now daily-exchange.timer

脚本参数

  • --once:跑一轮(timer 用这个,默认)
  • --loop --interval N:常驻循环,每 N 秒一轮(默认 3600,调试用)
  • 锁位置可用环境变量 DAILY_EXCHANGE_LOCK=/path/to.lock 覆盖

注意事项

  • 触发时间:OnCalendar=*-*-* 00:00:00。客户端文案已注明「可能存在延迟」,要错开整点扎堆可改 00:05:00
  • catch-up:Persistent=true,服务器宕机错过当天会在重启后补跑一轮。
  • DB 无关:sqlite / postgres 均可(不像美团 ETL 需要 PG)。
  • 改脚本 / 改部署:走 git + PR,由有 root 的人部署。