Files
Genarrative/deploy/container/README.md

5.8 KiB
Raw Blame History

Genarrative 容器化压测与隔离部署方案

本目录只服务本机或预发的容器化模拟压测,不替换当前生产 systemd + Nginx + Jenkins 发布路径。生产服务器仍以 deploy/systemd/deploy/nginx/scripts/jenkins-*.shscripts/deploy/production-api-deploy.sh 为准。

拓扑

Docker Compose
├─ spacetimedb  :3101独立数据卷供 api-server 连接
├─ nginx        :80 -> api-server:8082负责静态站点、/admin/、/api/ 反代、upstream timing log、连接限制
├─ api-server   :8082Linux release 构建,连接 compose 内 SpacetimeDB
├─ otelcol      :4317/4318debug 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=768mapi-server cpus=2.0 mem_limit=1gnginx cpus=0.25 mem_limit=128motelcol cpus=0.25 mem_limit=128mk6 cpus=0.5 mem_limit=512m。 Collector 镜像使用 otel/opentelemetry-collector-contrib:0.151.0。 生产服务器若启用 Collector则由 deploy/systemd/otelcol-contrib.servicedeploy/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。

如端口冲突,可设置:

$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"

初始化

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 发布模块:

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

启动与验证

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

查看日志:

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

容器内 api-server 资源上限与 Nginx 连接模型已经按 genarrative-release 的 2C / 2G / nofile=4096 / worker_connections=768 收口;如果你要改成别的机器,就先重新采样再改这里。

SpacetimeDB 容器默认只提供运行时,不自动发布模块。首次启动或清理 spacetime-data 卷后,先只启动 spacetimedb 服务,再发布模块:

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:upnpm run container:k6。如果 deploy/container/api-server.env 里的 GENARRATIVE_SPACETIME_DATABASE 改成了别的库名,发布命令里的库名也要同步修改。

如果要压 1000 HTTP req/sPEAK_RPS 调到 500;如果要压 5000 HTTP req/sPEAK_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.localdeploy/container/api-server.env 放入 Docker build context。
  • 不在容器镜像里内置 SpacetimeDB 数据或 token。