记录 Pingora dev 阶段验收
记录 dev 持久 shadow service 真实链路验收结果 记录 dev Nginx 前缀 canary 验收和恢复状态 补充 canary 前必须先完成持久 shadow 验收的口径
This commit is contained in:
@@ -63,6 +63,7 @@
|
||||
|
||||
- `deploy/nginx/snippets/genarrative-pingora-canary.conf` 是默认不启用的人工前缀 canary 入口,只在需要验证 Nginx -> Pingora handoff 时临时 include。它使用 `/__genarrative_pingora_canary/` 前缀改写后转发到 `127.0.0.1:18081`,并返回 `X-Genarrative-Nginx-Handoff: pingora-canary`。
|
||||
- `deploy/nginx/snippets/genarrative-pingora-realpath-canary.conf` 是前缀 canary 之后、direct 直连之前的真实路径 canary。它只能在 Nginx `http` 上下文人工 include,默认监听 `127.0.0.1:18083`,覆盖 `/api/creation-entry/config`、`/v1/identity`、`/v1/database/<db>/subscribe`、`/assets/app.js` 和拒绝入口,并写入独立 `/var/log/nginx/genarrative-pingora-realpath-canary.access.log`;不要把它 include 到生产 `443` server 内作为 location 覆盖。
|
||||
- 启用 Nginx canary 前,目标机必须已经有持久 `genarrative-pingora-gateway.service` 运行在 `127.0.0.1:18081`,且带真实 `api-server`、SpacetimeDB、静态目录和 `/var/log/genarrative/pingora-gateway.access.log` 完成本机 shadow 验收;不要从一次性 `/tmp` 网关进程直接切到 Nginx handoff。
|
||||
- 启用前必须运行 `npm run check:nginx-pingora-canary`;目标 agent 有 Nginx 时运行 `node scripts/check-nginx-pingora-canary.mjs --require-nginx`,同时做两个 snippet 的静态护栏和真实 `nginx -t`。本机或 CI 可运行 `npm run check:pingora-canary-docker`,用 Docker Nginx、真实 Pingora 和 mock 上游复现前缀 canary 与真实路径 canary 两条 handoff 链路。
|
||||
- 前缀 canary reload 后运行 `GENARRATIVE_PINGORA_CANARY_BASE_URL=http://127.0.0.1 GENARRATIVE_PINGORA_CANARY_HOST=<域名> npm run check:pingora-canary-live`,再用 `scripts/check-pingora-canary-access-log-parity.mjs` 对账 `/var/log/nginx/genarrative.access.log` 与 `/var/log/genarrative/pingora-gateway.access.log`。
|
||||
- 真实路径 canary reload 后运行 `node scripts/check-pingora-canary-live.mjs --realpath --base-url http://127.0.0.1:18083 --host <域名>`,再运行 `node scripts/check-pingora-canary-access-log-parity.mjs --realpath --nginx-log-file /var/log/nginx/genarrative-pingora-realpath-canary.access.log --pingora-log-file /var/log/genarrative/pingora-gateway.access.log --path /__genarrative_pingora_realpath_canary/healthz --path /api/creation-entry/config --path /v1/identity --path /assets/app.js`。真实路径模式除 healthz 探针外要求 Nginx path 与 Pingora path 完全一致。
|
||||
|
||||
@@ -312,7 +312,7 @@ node -- /opt/genarrative/current/scripts/deploy/pingora-health-patrol-env-switch
|
||||
当前 canary 只提供人工验证入口,不做随机流量抽样。启用步骤:
|
||||
|
||||
1. 在本地或 CI 先执行 `npm run check:pingora-canary-docker`;需要强制真实 Docker Nginx 链路时执行 `node scripts/check-pingora-canary-docker.mjs --require-docker --pull`。该脚本会同时验证 Docker Nginx access log 与 Pingora access log 的 `request_id` 对账,不只看 handoff 响应头。
|
||||
2. 确认 `genarrative-pingora-gateway.service` 已运行,且 `GENARRATIVE_PINGORA_GATEWAY_PROBE_TOKEN` 非空。
|
||||
2. 确认 `genarrative-pingora-gateway.service` 已作为持久 shadow service 运行在 `127.0.0.1:18081`,`GENARRATIVE_PINGORA_GATEWAY_PROBE_TOKEN` 非空,并已用真实 `api-server`、SpacetimeDB、静态 Web 目录和 access log 做过本机回环验收;不要直接从一次性 `/tmp` 进程进入 Nginx canary。
|
||||
3. 在目标机复制 `/etc/nginx/snippets/genarrative-pingora-canary.conf` 为临时启用版本,替换 `__GENARRATIVE_PINGORA_PROBE_TOKEN__`。
|
||||
4. 在 `server {}` 内人工 include 该 snippet,并保持 `allow 127.0.0.1; allow ::1; deny all;` 或改成当次可信来源。
|
||||
5. 执行 `npm run check:nginx-pingora-canary`;目标机或 CI 有 Nginx 时执行 `node scripts/check-nginx-pingora-canary.mjs --require-nginx`,再执行 `nginx -t && nginx -s reload`。
|
||||
@@ -321,6 +321,33 @@ node -- /opt/genarrative/current/scripts/deploy/pingora-health-patrol-env-switch
|
||||
8. 执行 current release 随包 `scripts/check-pingora-canary-access-log-parity.mjs --nginx-log-file /var/log/nginx/genarrative.access.log --pingora-log-file /var/log/genarrative/pingora-gateway.access.log --path /__genarrative_pingora_canary/healthz --path /__genarrative_pingora_canary/api/creation-entry/config`,确认同一 `request_id`、`path`、`status` 和 `proxy_target` 与 Nginx access log 可对齐。对账脚本的日志路径、canary prefix、必需路径和 `--since-lines` / `GENARRATIVE_PINGORA_CANARY_ACCESS_LOG_SINCE_LINES` 都不能包含换行或 NUL;若 access log 行里解析出的 URI / path 含控制字符,脚本也会把对应行记为失败,避免污染值进入 JSON 对账输出。
|
||||
9. 验证结束后移除 include 并 reload Nginx;不要把该前缀入口当作正式公网 URL。
|
||||
|
||||
## dev shadow service 验收记录
|
||||
|
||||
2026-06-17 已在 dev 机安装 `genarrative-pingora-gateway.service` 作为持久 shadow service。服务使用 `/opt/genarrative/current/pingora-gateway`,读取 `/etc/genarrative/pingora-gateway.env`,只监听 `127.0.0.1:18081`,上游保持 `api-server=127.0.0.1:8082`、`SpacetimeDB=127.0.0.1:3101`、静态目录 `/srv/genarrative/web`,access log 写入 `/var/log/genarrative/pingora-gateway.access.log`。probe token 只保存在目标机 env 文件,不进入仓库、终端日志或证据包。
|
||||
|
||||
本阶段验收只证明 shadow service 和真实上游链路可用,不启用 Nginx include,不 reload Nginx,不绑定公网 `80/443`。验收结果:
|
||||
|
||||
- `systemctl is-active genarrative-pingora-gateway.service` 返回 `active`,`NRestarts=0`。
|
||||
- `GET /__genarrative_pingora/healthz` 带 `X-Genarrative-Pingora-Probe` 返回 `200` 和 `gateway=pingora-shadow`,不带 token 返回 `404`。
|
||||
- `GET /api/creation-entry/config` 经 Pingora 转发到真实 `api-server`,返回 `200 application/json`。
|
||||
- `GET /` 从真实 Web 目录返回 `200 text/html`。
|
||||
- `GET /v1/identity` 经 Pingora 转发到真实 SpacetimeDB,返回 `405 Method Not Allowed`;这是当前 SpacetimeDB 对 GET identity 的真实语义,只作为路径转发代表。
|
||||
- `GET /v1/database/genarrative-prod/subscribe?compression=Brotli` WebSocket Upgrade 经 Pingora 转发到真实 SpacetimeDB,返回 `101 Switching Protocols`,并带 `X-Genarrative-Gateway: pingora-shadow`。
|
||||
- `/var/log/genarrative/pingora-gateway.access.log` 已记录 healthz、API、静态、SpacetimeDB identity 和 WSS subscribe 的 `request_id`、`path`、`status`、`proxy_target` 与 `upstream`。
|
||||
|
||||
dev 根盘空间在安装后曾接近满盘;2026-06-17 进入 canary 前已清理旧 `/tmp/genarrative-*` 临时部署目录、apt cache,并将 journald 收敛到约 `512M`,`df -h /` 从 `100%` 降到约 `92%`。后续 canary / 证据归档前仍应复核 `df -h /`,避免 access log、Nginx reload 或证据归档阶段被磁盘空间干扰。
|
||||
|
||||
## dev Nginx prefix canary 验收记录
|
||||
|
||||
2026-06-17 已在 dev 机做过一次临时 Nginx prefix canary。步骤是将 `deploy/nginx/snippets/genarrative-pingora-canary.conf` 渲染到 `/etc/nginx/snippets/genarrative-pingora-canary.conf`,只在 `dev.genarrative.world` 的本机 HTTP `server {}` 内临时 include,执行 `nginx -t && nginx -s reload` 后用 `http://127.0.0.1` 与 `Host: dev.genarrative.world` 做 loopback 验收。验证结束后已恢复 `/etc/nginx/conf.d/genarrative.conf` 备份并 reload Nginx;当前正常公网入口仍由 Nginx 原配置承接,Pingora 继续只作为 `127.0.0.1:18081` shadow service 运行。
|
||||
|
||||
本阶段验收只证明 Nginx -> Pingora 的前缀 handoff 可用,不做真实路径 canary,不切 `80/443` 到 Pingora。验收结果:
|
||||
|
||||
- `node /tmp/check-pingora-canary-live.mjs --base-url http://127.0.0.1 --host dev.genarrative.world --json` 通过:healthz `200`、API config `200`、SpacetimeDB identity `405`、静态代表路径 `404`、generated 拒绝路径 `404`,全部带 `X-Genarrative-Nginx-Handoff: pingora-canary`。
|
||||
- 通过 Nginx 前缀 canary 访问 `/__genarrative_pingora_canary/v1/database/genarrative-prod/subscribe?compression=Brotli`,WebSocket Upgrade 返回 `101 Switching Protocols`,并带 `sec-websocket-protocol: v2.bsatn.spacetimedb`、`X-Genarrative-Nginx-Handoff: pingora-canary` 和 `X-Genarrative-Gateway: pingora-shadow`。
|
||||
- `node /tmp/check-pingora-canary-access-log-parity.mjs --nginx-log-file /var/log/nginx/genarrative.access.log --pingora-log-file /var/log/genarrative/pingora-gateway.access.log ... --json` 对账 `6/6 matched`,`missingCount=0`,`mismatchCount=0`;覆盖 healthz、API config、SpacetimeDB identity、WSS subscribe、静态代表路径和 generated 拒绝路径。
|
||||
- 恢复后 `grep genarrative-pingora-canary /etc/nginx/conf.d/genarrative.conf` 无匹配,`GET http://127.0.0.1/__genarrative_pingora_canary/healthz` 在正常 Nginx HTTP 入口回到 `301`,证明临时 canary include 已移除;`genarrative-pingora-gateway.service` 仍为 `active` 且 `NRestarts=0`。
|
||||
|
||||
## 环境变量
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|
||||
Reference in New Issue
Block a user