diff --git a/PROGRESS.md b/PROGRESS.md index d8da114..f491d96 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2,7 +2,7 @@ > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。 -最后更新:2026-07-06(部署 pip 输出精简,bump 0.42.2) +最后更新:2026-07-06(nginx TLS 示例与 497 跳转坑位文档,bump 0.42.3) --- @@ -23,6 +23,7 @@ ### 2026-07 +- **07-06 / 0.42.3**:nginx 示例补 TLS 正确写法(同端口单条 listen + error_page 497 跳 https;`if ($scheme)` 在 ssl-only 端口不触发)+ 企微回调只认 80/443 提醒;实际部署上 SSL 踩出,进故障兜底。 - **07-06 / 0.42.2**:部署脚本 pip install 加 `-q`——日常部署依赖没变,整屏 "already satisfied" 纯刷屏;装新包/报错仍输出。 - **07-06 / 0.42.1**:修 `update_bluegreen.sh` wait_health 首次真跑就崩——`local a="$1" b="...$a..."` 同行赋值,bash 先展开整行再执行 local,`$a` 展开时无值,`set -u` 报 unbound;拆多行。 - **07-06 / 0.42.0 broker 外置 Redis(用户量上升重评落地)**:`web/broker.py` 拆 LocalRunBroker(原进程内实现)/ RedisRunBroker 同接口双实现,`ZCBOT_REDIS_URL` env 开关(不设 = 进程内,dev/单实例零影响)。Redis 版:event 走 PUBLISH + 单条 async pubsub reader 路由本地 queue,done = SETEX(60s)+publish 双通道(订阅先挂 channel 再查 key 不漏),cancel = key GET poll 跨实例可达——蓝绿切换窗口「刷新丢直播/停止失灵」两边缘消失,稳态双实例分流从此只差 nginx 配置。容错:启动 ping fail-fast、运行中降级丢帧(10s 节流 log)、reader 1s 退避重连。`tests/test_broker_redis.py` 9 例(fakeredis,含跨实例/晚订阅/降级);deploy bootstrap 加 redis-server 步骤。关键判断:排除 PG LISTEN/NOTIFY(token delta 耦主库)与 nginx sticky(部署窗 hash 重排),Redis 只管跨进程一跳、fan-out 最后一公里仍在进程内。 diff --git a/RUN.md b/RUN.md index 630f07d..cae3398 100644 --- a/RUN.md +++ b/RUN.md @@ -854,6 +854,7 @@ sudo xfs_quota -x -c "limit -p bhard=10g zcbot_" /opt | 蓝绿切换后用户直播不动、但任务其实在跑 | 用户恰在切换窗口刷新页面,run 还在旧实例上而 SSE 连到了新实例(broker 进程内不跨实例)。run 照常跑完落库,等旧实例日志安静后让用户刷新看历史;非 bug,已知边缘 | | 蓝绿并存期微信 ClawBot 没反应 | 入站长轮询走 PG advisory lock 选主。两实例 journalctl 里找 `[wechat] inbound leader lock acquired`——都没有 → 检查 DB 连通;锁在已停实例上不可能(连接断锁即释),新实例最长 15s 接管 | | 蓝绿部署后旧色 sandbox 容器残留 | 正常:旧实例 stop 时 `shutdown_all` 只清自己色,失败/超时的靠下次该色启动兜底。手动清:`docker rm -f $(docker ps -aq -f label=zcbot.instance=<色>)` | +| nginx 上 TLS 后 `nginx -t` 报 `duplicate listen options` / HTTP 跳转不生效 | 同端口只能一条 listen(`listen 8765 ssl` 与 `listen 8765` 不能并存);「HTTP 自动跳 HTTPS(同端口)」用 `error_page 497 =301 https://$host:8765$request_uri;`——`if ($scheme = http)` 在 ssl-only 端口永远不触发(握手层就报 497)。模板见 deploy/nginx/zcbot.conf.example TLS 注释段 | | 启动报 `ZCBOT_REDIS_URL 已设但 Redis 连不上` | redis-server 没起 / URL 错。`systemctl status redis-server` + `redis-cli ping` 验;或从 `.env` 删掉该行回退进程内 broker(蓝绿切换边缘会回来,见「broker 外置」段) | | 日志刷 `[broker] redis publish failed`(10s 节流) | redis 运行中挂了。降级:直播丢帧、SSE 卡 ping,run 本身照常跑完落库;`systemctl restart redis-server` 恢复后 pubsub reader 1s 退避自动重连,无需重启 zcbot | | 蓝绿切换窗口刷新丢直播 / 停止失灵(设了 ZCBOT_REDIS_URL 仍出现) | 两实例 journalctl 找 `[broker] redis pub/sub enabled` —— 没有 = 该实例没读到 env(改完 .env 没 restart 实例);有但仍异常看是否伴随 publish failed(redis 本身故障) | diff --git a/core/__init__.py b/core/__init__.py index 19b008f..f001ce4 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,3 +1,3 @@ # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # 改版本只动这一行。 -__version__ = "0.42.2" +__version__ = "0.42.3" diff --git a/deploy/nginx/zcbot.conf.example b/deploy/nginx/zcbot.conf.example index cd179d4..9260c76 100644 --- a/deploy/nginx/zcbot.conf.example +++ b/deploy/nginx/zcbot.conf.example @@ -18,10 +18,21 @@ upstream zcbot_backend { } server { - # 对外沿用原单实例端口,客户端无感;上 TLS 时换 listen 443 ssl + 证书(certbot 等) + # 对外沿用原单实例端口,客户端无感 listen 8765; server_name _; + # ── 上 TLS 时:上面 listen 换成下面这段(同端口只能一条 listen,ssl 与明文不能并存)── + # listen 8765 ssl; + # server_name bot.example.com; + # ssl_certificate /path/to/fullchain.pem; + # ssl_certificate_key /path/to/privkey.pem; + # # 明文 HTTP 打到 ssl 端口 → nginx 报 497,借它 301 跳 https。 + # # 注意 `if ($scheme = http)` 在 ssl-only 端口永远不触发(握手层就 497 了),别用。 + # error_page 497 =301 https://$host:8765$request_uri; + # # 企业微信回调 / OAuth 可信域名只认 80/443 标准端口 —— 要用企微入站/扫码登录, + # # 另加一个 listen 443 ssl 的 server 块同样 proxy 到 zcbot_backend。 + # 上传接口(/v1/files/upload)会传大文件;与后端无硬限制,给足余量 client_max_body_size 512m;