155 lines
5.8 KiB
Markdown
155 lines
5.8 KiB
Markdown
# Genarrative 容器化压测与隔离部署方案
|
||
|
||
本目录只服务本机或预发的容器化模拟压测,不替换当前生产 `systemd + Nginx + Jenkins` 发布路径。生产服务器仍以 `deploy/systemd/`、`deploy/nginx/`、`scripts/jenkins-*.sh` 和 `scripts/deploy/production-api-deploy.sh` 为准。
|
||
|
||
## 拓扑
|
||
|
||
```text
|
||
Docker Compose
|
||
├─ spacetimedb :3101,独立数据卷,供 api-server 连接
|
||
├─ nginx :80 -> api-server:8082,负责静态站点、/admin/、/api/ 反代、upstream timing log、连接限制
|
||
├─ api-server :8082,Linux release 构建,连接 compose 内 SpacetimeDB
|
||
├─ otelcol :4317/4318,debug exporter,接收 traces / metrics / logs
|
||
└─ k6 profile=loadtest 时临时启动,在 compose 网络内压 nginx
|
||
```
|
||
|
||
当前容器模拟参数按 `genarrative-release` 服务器采样值收口为 2 vCPU / 2 GiB RAM / 4096 soft nofile / 768 worker_connections,并已在 compose 里落实到 `spacetimedb cpus=1.0 mem_limit=768m`、`api-server cpus=2.0 mem_limit=1g`、`nginx cpus=0.25 mem_limit=128m`、`otelcol cpus=0.25 mem_limit=128m`、`k6 cpus=0.5 mem_limit=512m`。
|
||
Collector 镜像使用 `otel/opentelemetry-collector-contrib:0.151.0`。
|
||
生产服务器若启用 Collector,则由 `deploy/systemd/otelcol-contrib.service` 和 `deploy/otelcol/genarrative-debug.yaml` 托管,不走容器镜像。
|
||
|
||
默认 host 端口:
|
||
|
||
- `http://127.0.0.1:13101`:容器 SpacetimeDB。
|
||
- `http://127.0.0.1:18080`:容器 Nginx。
|
||
- `127.0.0.1:4317` / `127.0.0.1:4318`:容器 Collector OTLP gRPC / HTTP。
|
||
|
||
如端口冲突,可设置:
|
||
|
||
```powershell
|
||
$env:GENARRATIVE_CONTAINER_SPACETIME_PORT="13102"
|
||
$env:GENARRATIVE_CONTAINER_HTTP_PORT="18081"
|
||
$env:GENARRATIVE_CONTAINER_OTLP_HTTP_PORT="14318"
|
||
$env:GENARRATIVE_CONTAINER_OTLP_GRPC_PORT="14317"
|
||
```
|
||
|
||
## 初始化
|
||
|
||
```bash
|
||
npm run container:init
|
||
```
|
||
|
||
该命令会从 `deploy/container/api-server.env.example` 生成本地 `deploy/container/api-server.env`。真实 token、库名和外部服务密钥只写本地 env 文件,不提交 Git。
|
||
|
||
Docker Desktop 下默认通过 `http://spacetimedb:3101` 连接 compose 内 SpacetimeDB;宿主机只负责用 CLI 发布模块:
|
||
|
||
```env
|
||
GENARRATIVE_SPACETIME_SERVER_URL=http://spacetimedb:3101
|
||
GENARRATIVE_SPACETIME_DATABASE=genarrative-loadtest
|
||
GENARRATIVE_SPACETIME_TOKEN=
|
||
```
|
||
|
||
宿主机发布模块时,先用 CLI 向 `http://127.0.0.1:13101` 发布到 `genarrative-loadtest`,再启动 `npm run container:up`。
|
||
|
||
Linux Docker Engine 若要从宿主机 CLI 连到容器内服务,直接用 `http://127.0.0.1:13101`;容器内部服务之间统一走 `http://spacetimedb:3101`。
|
||
|
||
## 启动与验证
|
||
|
||
```bash
|
||
npm run container:config
|
||
npm run container:build
|
||
npm run container:up -- spacetimedb
|
||
spacetime publish genarrative-loadtest --server http://127.0.0.1:13101 --module-path server-rs/crates/spacetime-module --yes --build-options="--debug"
|
||
npm run container:up
|
||
npm run container:ps
|
||
curl -sS http://127.0.0.1:18080/api/runtime/puzzle/gallery
|
||
```
|
||
|
||
查看日志:
|
||
|
||
```bash
|
||
npm run container:logs -- nginx
|
||
npm run container:logs -- api-server
|
||
npm run container:logs -- otelcol
|
||
```
|
||
|
||
`npm run container:config` 默认只校验配置,不打印完整 env。排查 compose 展开结果时可临时使用:
|
||
|
||
```bash
|
||
npm run container:config -- --print
|
||
```
|
||
|
||
如果 `deploy/container/api-server.env` 已写入真实 token,不要把完整展开结果贴到公开渠道。
|
||
|
||
停止:
|
||
|
||
```bash
|
||
npm run container:down
|
||
```
|
||
|
||
如需同时清理容器卷:
|
||
|
||
```bash
|
||
npm run container:down -- -v
|
||
```
|
||
|
||
## 压测
|
||
|
||
k6 在 compose 网络内访问 `http://nginx`,避免 Windows 本机直连连接模型干扰 Linux 容器结果:
|
||
|
||
```bash
|
||
npm run container:k6
|
||
```
|
||
|
||
作品列表脚本一次 iteration 默认请求两个公开列表接口,因此目标 500 HTTP req/s 对应 `PEAK_RPS=250`:
|
||
|
||
```powershell
|
||
$env:SCENARIO="spike"
|
||
$env:START_RPS="25"
|
||
$env:PEAK_RPS="250"
|
||
$env:HOLD="60s"
|
||
$env:END_RPS="25"
|
||
$env:PREALLOCATED_VUS="100"
|
||
$env:MAX_VUS="500"
|
||
$env:DETAIL_RATIO="0"
|
||
npm run container:k6
|
||
```
|
||
|
||
容器内 `api-server` 资源上限与 Nginx 连接模型已经按 `genarrative-release` 的 2C / 2G / `nofile=4096` / `worker_connections=768` 收口;如果你要改成别的机器,就先重新采样再改这里。
|
||
|
||
SpacetimeDB 容器默认只提供运行时,不自动发布模块。首次启动或清理 `spacetime-data` 卷后,先只启动 `spacetimedb` 服务,再发布模块:
|
||
|
||
```bash
|
||
npm run container:up -- spacetimedb
|
||
spacetime publish genarrative-loadtest --server http://127.0.0.1:13101 --module-path server-rs/crates/spacetime-module --yes --build-options="--debug"
|
||
```
|
||
|
||
发布完成后再执行 `npm run container:up` 和 `npm run container:k6`。如果 `deploy/container/api-server.env` 里的 `GENARRATIVE_SPACETIME_DATABASE` 改成了别的库名,发布命令里的库名也要同步修改。
|
||
|
||
如果要压 1000 HTTP req/s,把 `PEAK_RPS` 调到 `500`;如果要压 5000 HTTP req/s,把 `PEAK_RPS` 调到 `2500`,并同时提高 `PREALLOCATED_VUS` / `MAX_VUS`,观察是否先被带宽、Nginx `limit_conn` 或 api-server 背压限制。
|
||
|
||
## OTLP
|
||
|
||
容器内 `otelcol` 默认使用 debug exporter。开启 api-server OTEL:
|
||
|
||
```env
|
||
GENARRATIVE_OTEL_ENABLED=true
|
||
OTEL_EXPORTER_OTLP_ENDPOINT=http://otelcol:4318
|
||
```
|
||
|
||
然后重建或重启容器:
|
||
|
||
```bash
|
||
npm run container:up
|
||
npm run container:logs -- otelcol
|
||
```
|
||
|
||
Collector 日志会输出 traces / metrics / logs。接 Rider、Jaeger、Tempo、Prometheus、Grafana 或托管平台时,另建独立 Collector 配置,不直接改生产 systemd 或 Nginx 模板。
|
||
|
||
## 隔离边界
|
||
|
||
- 不改生产 systemd 单元。
|
||
- 不改 Jenkins 发布主流程。
|
||
- 不要求真实 HTTPS 证书。
|
||
- 不把真实 `.env`、`.env.local`、`.env.secrets.local` 或 `deploy/container/api-server.env` 放入 Docker build context。
|
||
- 不在容器镜像里内置 SpacetimeDB 数据或 token。
|