新增 Pingora 独立网关试点

新增 pingora-gateway 独立二进制 crate,复刻当前 Nginx 核心路由口径

接入 Pingora 依赖、workspace 成员和锁文件

补充 Pingora 影子网关运维文档、环境变量示例和 Hermes 决策记录
This commit is contained in:
2026-06-11 16:51:28 +08:00
parent 7dd53e95d8
commit f7ca9d0672
8 changed files with 1884 additions and 59 deletions
@@ -0,0 +1,66 @@
# Pingora 独立网关试点
## 目标
本试点新增 `server-rs/crates/pingora-gateway` 独立二进制 crate,用 Pingora 复刻当前生产 Nginx 的核心反向代理与静态路由口径。当前阶段只作为影子网关验证,不绑定公网 `80/443`,不替代 `deploy/nginx/genarrative.conf`
## 运行边界
- 默认监听 `127.0.0.1:18081`,只用于本机或容器内 smoke。
- 默认转发 `api-server``127.0.0.1:8082`
- 默认转发最小 SpacetimeDB 公网路由到 `127.0.0.1:3101`
- 默认静态目录为 `/srv/genarrative/web`,维护开关文件为 `/var/lib/genarrative/maintenance/enabled`
- 当前不承接 TLS、HTTP 到 HTTPS 跳转、gzip/Brotli、完整连接数限制、完整 RPS 限流、Certbot ACME 自动化、Jenkins 产物发布和 systemd 健康巡检。
## 启动命令
本机影子验证时先启动 SpacetimeDB 与 `api-server`,再运行:
```bash
GENARRATIVE_PINGORA_GATEWAY_WEB_ROOT=/srv/genarrative/web \
cargo run -p pingora-gateway --manifest-path server-rs/Cargo.toml
```
也可以复制 `deploy/pingora/pingora-gateway.env.example` 到部署环境的非 Git 配置文件,由 systemd 或容器注入。
## 环境变量
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `GENARRATIVE_PINGORA_GATEWAY_LISTEN` | `127.0.0.1:18081` | Pingora 监听地址。 |
| `GENARRATIVE_PINGORA_GATEWAY_API_UPSTREAM` | `127.0.0.1:8082` | `api-server` 上游地址。 |
| `GENARRATIVE_PINGORA_GATEWAY_SPACETIME_UPSTREAM` | `127.0.0.1:3101` | SpacetimeDB 上游地址。 |
| `GENARRATIVE_PINGORA_GATEWAY_WEB_ROOT` | `/srv/genarrative/web` | 前端静态文件根目录。 |
| `GENARRATIVE_PINGORA_GATEWAY_ACME_ROOT` | `/var/www/html` | ACME challenge 静态目录。 |
| `GENARRATIVE_PINGORA_GATEWAY_MAINTENANCE_FILE` | `/var/lib/genarrative/maintenance/enabled` | 存在即进入维护模式。 |
| `GENARRATIVE_PINGORA_GATEWAY_FORWARDED_PROTO` | `http` | 写入 `X-Forwarded-Proto` 的值。 |
| `GENARRATIVE_PINGORA_GATEWAY_MAX_API_BODY_BYTES` | `67108864` | `/api` 通用路由的 `Content-Length` 上限。 |
| `GENARRATIVE_PINGORA_GATEWAY_LOG` | `info,pingora=info,pingora_gateway=info` | tracing 过滤器。 |
| `GENARRATIVE_PINGORA_GATEWAY_OTEL_ENABLED` | `false` | 是否启用共享 OpenTelemetry 初始化。 |
## 当前路由口径
| 路由 | 行为 |
| --- | --- |
| `/.well-known/acme-challenge/*` | 从 `GENARRATIVE_PINGORA_GATEWAY_ACME_ROOT` 精确读取静态文件。 |
| `/admin` | 301 到 `/admin/`。 |
| `/admin/api/*` | 转发到 `api-server`。 |
| `/admin/assets/*` | 从 Web 根目录精确读取静态文件。 |
| `/admin/*` | 先读取静态文件或目录 index,失败回退 `/admin/index.html`。 |
| `/assets/*` | 从 Web 根目录精确读取静态文件。 |
| `/api/runtime/puzzle/gallery``/api/runtime/custom-world-gallery` | 转发到 `api-server`。 |
| `/api/runtime/puzzle/gallery/{id}``/api/runtime/custom-world-gallery/{profile}/{owner}` | 转发到 `api-server`。 |
| `/api``/api/*` | 转发到 `api-server`,按配置执行 `Content-Length` 上限检查。 |
| `/v1/database/{db}/subscribe``/v1/identity*` | 转发到 SpacetimeDB,保留 WebSocket Upgrade 头。 |
| `/v1/*``/generated-*``/healthz*``/readyz*` | 返回 404,保持生产公网不暴露口径。 |
| 其它路径 | 先读取静态文件或目录 index,失败回退 `/index.html`。 |
维护模式下,API-like 路由返回 JSON `503`Web 静态路由优先返回 `maintenance.html`,不存在时返回纯文本 `503`
## 后续替换前验收
1. 容器内使用同一份 Web 产物、同一组上游地址跑 Pingora smoke。
2. 对照 `deploy/nginx/genarrative.conf` 做路由 parity 自动测试,覆盖 API、Admin、SPA fallback、静态资源、维护模式和 SpacetimeDB WebSocket。
3. 补齐限流、连接数限制、压缩、TLS、ACME 和访问日志字段。
4. 增加 systemd service 模板与健康巡检,但仍由 Nginx 反向代理到 Pingora 做 canary。
5. canary 稳定后,再评估是否让 Pingora 直接承接公网入口。