docs: 规模设定重评——broker 外置 Redis 由搁置转推荐实施(bump 0.41.2)
用户量已非个位数,DESIGN §7.0/§8.4 与 RUN.md 蓝绿节的"当前规模不值得上 Redis"设定过时:①部署时总有 in-flight run,蓝绿窗口边缘常态化;②稳态双实例 分流是最近的扩容手段,broker 外置是硬前提。选型排除 PG LISTEN/NOTIFY(token 级 delta 耦主库)与 nginx sticky(upstream 变更时 hash 重排恰在部署窗失效)。 实施待确认,方案要点已记 DESIGN §7.0。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
242548ea84
commit
bb6fd11dbb
|
|
@ -125,7 +125,9 @@ Session = 消息列表,ORM 直写 PG `messages`(append-only,jsonb 存 LiteLLM
|
|||
|
||||
同一份 web `/v1` 服务换部署位置:Storage 都是 PG(换 `ZCBOT_DB_URL`);working_dir/memory 换外层根目录;Sandbox 本地 subprocess → SaaS per-user 容器;Auth 邮箱密码 + platform_key→JWT → 未来 OIDC(邮箱密码长期并存)。`workspace/` 仅存产物,state/messages 全在 PG。
|
||||
|
||||
**无感部署(蓝绿,0.41)**:生产双 systemd 实例(`ZCBOT_INSTANCE=blue/green`)+ nginx upstream 切流,取代单实例 restart 的 503 窗口。取舍:**event broker 刻意留在进程内**(不上 Redis pub/sub)——代价只是"切换瞬间刷新页面的用户看不到旧实例上 run 的直播"(run 照常落库),当前规模不值得为此引基础设施。双实例并存的互踩由三件事消解:`tasks.run_owner`(0020)让 reaper 只收自己色、sandbox 容器名/label 带实例色各管各的、微信长轮询 PG advisory lock 选主;定时任务 claim 本就 SKIP LOCKED 天然安全。部署编排在 `deploy/update_bluegreen.sh`(流程/兜底见 RUN)。
|
||||
**无感部署(蓝绿,0.41)**:生产双 systemd 实例(`ZCBOT_INSTANCE=blue/green`)+ nginx upstream 切流(对外仍 8765),取代单实例 restart 的 503 窗口。双实例并存的互踩由三件事消解:`tasks.run_owner`(0020)让 reaper 只收自己色、sandbox 容器名/label 带实例色各管各的、微信长轮询 PG advisory lock 选主;定时任务 claim 本就 SKIP LOCKED 天然安全。部署编排在 `deploy/update_bluegreen.sh`(流程/兜底见 RUN)。
|
||||
|
||||
**broker 外置(Redis pub/sub)**:0.41 落地时 event/cancel broker 留在进程内,代价是切换窗口内"刷新看不到旧实例 run 直播 / 停止送达不到"两个边缘。**2026-07-06 重评(用户量已非个位数):由"搁置到真实投诉"转为"推荐实施"** —— ①部署时总有 in-flight run,窗口边缘从偶发变常态;②单进程逼近天花板后,最近的扩容手段是稳态双实例同时接流量,broker 外置是它的硬前提(否则 POST 与 SSE 落不同实例直播全瞎)。选 Redis 不选 PG LISTEN/NOTIFY(token 级 delta 全过主库太吵:NOTIFY 全局队列 + 8KB payload 限制,把实时路径耦到 PG)、不选 nginx sticky hash(upstream 变更时 hash 重排,恰在部署窗口失效,治标)。方案:`ZCBOT_REDIS_URL` env 开关,不设即回退进程内(dev 零影响);done 语义改查 DB run_status + done key(天然跨实例);cancel 改 Redis key poll。Redis 不解决的:run 本体仍绑进程(进程死 run 死,drain/reaper 不变)、线程池上限(调 `ZCBOT_RUN_MAX_WORKERS` 的事)。
|
||||
|
||||
### 7.1 心智模型:Task 一等公民 + Dir 文件副视图
|
||||
|
||||
|
|
@ -262,7 +264,7 @@ scheduled_jobs(§8.5) channel_bindings(§8.7,判别列+JSONB)
|
|||
|
||||
### 8.4 运维监控 / 无感更新(监控 ✅ / 换版 design)
|
||||
|
||||
**优雅 drain 已是单实例上限**(SIGTERM 拒新 run + 等收尾);先撞的瓶颈是线程池(每活跃 run 占 1 线程)。落地排序:① 轻量监控(显式 executor + 60s `[stats]` 周期日志——要历史峰值不是快照);② 按数据决策扩容;③ `--reload` 缩 503 窗。**不做监控界面**:运维健康是少数标量,日志够;业务分析走 DB SQL。界面阶梯:日志 → /v1/stats → Grafana → 只读 dashboard,现停第一级。gunicorn 无感换版 / broker 外置 Redis 搁置到真实投诉。
|
||||
**优雅 drain 已是单实例上限**(SIGTERM 拒新 run + 等收尾);先撞的瓶颈是线程池(每活跃 run 占 1 线程)。落地排序:① 轻量监控(显式 executor + 60s `[stats]` 周期日志——要历史峰值不是快照);② 按数据决策扩容;③ `--reload` 缩 503 窗。**不做监控界面**:运维健康是少数标量,日志够;业务分析走 DB SQL。界面阶梯:日志 → /v1/stats → Grafana → 只读 dashboard,现停第一级。无感换版已由蓝绿落地(0.41,见 §7.0);broker 外置 Redis 2026-07-06 重评为推荐实施(§7.0),扩容路径:调大线程池 → 稳态双实例分流(broker 外置后纯 nginx 配置动作)。
|
||||
|
||||
### 8.5 定时任务(✅ 2026-06-18)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
> 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。
|
||||
|
||||
最后更新:2026-07-06(蓝绿端口方案改 nginx 接管 8765,bump 0.41.1)
|
||||
最后更新:2026-07-06(规模设定重评:broker 外置 Redis 转推荐实施,bump 0.41.2)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
2
RUN.md
2
RUN.md
|
|
@ -321,7 +321,7 @@ sudo bash /opt/zcbot/deploy/update_bluegreen.sh
|
|||
|
||||
脚本流程:`update.sh --prepare-only`(拉码 / pip / migration / build,全复用单实例脚本)→ 起空闲色实例 → healthz 验活(核对 `instance` 字段)→ 改写 upstream + nginx reload(**新请求全走新实例,零 503**)→ **轮询 DB 等旧色在跑 run 自然清空**(上限 `DRAIN_WAIT_SECONDS`,期间旧 SSE 继续直播不断流 —— 直接 stop 的话 uvicorn `timeout_graceful_shutdown=5` 会 5s 掐长连接)→ stop 旧实例(残留 run 走 SIGTERM drain / 协作式 cancel)→ 旧色 SIGKILL 残留的 running 行标 error → enable 新色 / disable 旧色(重启机器只拉起 live 色)。
|
||||
|
||||
效果 vs 单实例 `update.sh`:**没有 503 窗口,在跑对话的 SSE 直播也不断**。已知边缘(接受,仅存在于切换后旧色 drain 的几分钟窗口内、且 run 恰好还在旧实例上):① 用户刷新页面 → SSE 连到新实例,broker 没有该 run 的事件,直播看不到(run 照常在旧实例跑完落库,完了刷新看历史);② 点「停止」→ cancel 信号进的是新实例的进程内 broker,旧实例收不到,等 run 自然收尾即可。两者根因同一个:event/cancel broker 是进程内的(`web/broker.py`)不跨实例 —— 刻意取舍,当前规模不值得上 Redis pub/sub(取舍详见 DESIGN §7.0)。
|
||||
效果 vs 单实例 `update.sh`:**没有 503 窗口,在跑对话的 SSE 直播也不断**。已知边缘(接受,仅存在于切换后旧色 drain 的几分钟窗口内、且 run 恰好还在旧实例上):① 用户刷新页面 → SSE 连到新实例,broker 没有该 run 的事件,直播看不到(run 照常在旧实例跑完落库,完了刷新看历史);② 点「停止」→ cancel 信号进的是新实例的进程内 broker,旧实例收不到,等 run 自然收尾即可。两者根因同一个:event/cancel broker 是进程内的(`web/broker.py`)不跨实例。**2026-07-06 重评(用户量上升):broker 外置 Redis 已转为推荐实施**(消掉这两个边缘 + 为稳态双实例分流铺路,取舍与方案见 DESIGN §7.0);实施落地前此边缘仍在。
|
||||
|
||||
蓝绿并存期的互踩问题已在代码层解决(单实例部署 `ZCBOT_INSTANCE` 未设,以下全部退回原行为):
|
||||
- **启动 reaper**:`tasks.run_owner`(migration 0020)记 run 归属实例,实例启动只收自己色(+ NULL 遗留)的孤儿 run,不误杀另一实例在跑的
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.41.1"
|
||||
__version__ = "0.41.2"
|
||||
|
|
|
|||
Loading…
Reference in New Issue