Genarrative 容器化压测与隔离部署方案
本目录只服务本机或预发的容器化模拟压测,不替换当前生产 systemd + Nginx + Jenkins 发布路径。生产服务器仍以 deploy/systemd/、deploy/nginx/、scripts/jenkins-*.sh 和 scripts/deploy/production-api-deploy.sh 为准。
拓扑
Docker Compose
├─ nginx :80 -> api-server:8082,负责静态站点、/admin/、/api/ 反代、upstream timing log、连接限制
├─ api-server :8082,Linux release 构建,连接外部 SpacetimeDB
├─ otelcol :4317/4318,debug exporter,接收 traces / metrics / logs
└─ k6 profile=loadtest 时临时启动,在 compose 网络内压 nginx
默认 host 端口:
http://127.0.0.1:18080:容器 Nginx。127.0.0.1:4317/127.0.0.1:4318:容器 Collector OTLP gRPC / HTTP。
如端口冲突,可设置:
$env:GENARRATIVE_CONTAINER_HTTP_PORT="18081"
$env:GENARRATIVE_CONTAINER_OTLP_HTTP_PORT="14318"
$env:GENARRATIVE_CONTAINER_OTLP_GRPC_PORT="14317"
初始化
npm run container:init
该命令会从 deploy/container/api-server.env.example 生成本地 deploy/container/api-server.env。真实 token、库名和外部服务密钥只写本地 env 文件,不提交 Git。
Docker Desktop 下默认通过 host.docker.internal:3101 连接宿主机上 npm run dev 启动的 SpacetimeDB:
GENARRATIVE_SPACETIME_SERVER_URL=http://host.docker.internal:3101
GENARRATIVE_SPACETIME_DATABASE=genarrative-loadtest
GENARRATIVE_SPACETIME_TOKEN=
Linux Docker Engine 如果不能解析 host.docker.internal,Compose 已配置 host-gateway;仍不通时把 GENARRATIVE_SPACETIME_SERVER_URL 改成宿主机网关 IP 或同网络内的 SpacetimeDB 地址。
启动与验证
npm run container:config
npm run container:build
npm run container:up
npm run container:ps
curl -sS http://127.0.0.1:18080/api/runtime/puzzle/gallery
查看日志:
npm run container:logs -- nginx
npm run container:logs -- api-server
npm run container:logs -- otelcol
npm run container:config 默认只校验配置,不打印完整 env。排查 compose 展开结果时可临时使用:
npm run container:config -- --print
如果 deploy/container/api-server.env 已写入真实 token,不要把完整展开结果贴到公开渠道。
停止:
npm run container:down
如需同时清理容器卷:
npm run container:down -- -v
压测
k6 在 compose 网络内访问 http://nginx,避免 Windows 本机直连连接模型干扰 Linux 容器结果:
npm run container:k6
作品列表脚本一次 iteration 默认请求两个公开列表接口,因此目标 500 HTTP req/s 对应 PEAK_RPS=250:
$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
如果要压 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:
GENARRATIVE_OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://otelcol:4318
然后重建或重启容器:
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。