部署

生产拓扑、横向扩展、外部指标与追踪、备份与升级,以及随附参考清单的状态。

在生产环境运行 Cordy Gateway 的受支持方式,是同时使用 docker-compose.prod.yml 与文档中的 docker-compose.production-overrides.yml。本页介绍生产拓扑、如何扩展、连接由运维管理的可观测性,以及第二天运维。首次起栈请从快速开始开始。

生产拓扑

docker-compose.prod.yml 在一台 Docker 主机上运行完整技术栈:

   客户端 ──► nginx ──► gateway(1..N 副本)──► pgbouncer ──► postgres
                (LB / TLS)         │                                 ▲
                                   └──────────► redis                │
                                                                worker ┘
   管理员 ──► admin(Django)─────────────────► postgres, redis
服务角色暴露
nginx负载均衡与 TLS 终止点;在网关副本间轮询发布 GATEWAY_HTTP_PORT(默认 8002
gateway数据平面;可扩展到 N 副本内部 8002,在 nginx 之后
admin控制平面(Django)发布 ADMIN_HTTP_PORT(默认 8001
pgbouncer网关热路径的事务池仅内部
postgresPostgreSQL 18 + pg_cron仅内部
redis速率限制、配额、缓存、冷却、幂等、缓冲仅内部
worker后台用量结算与审计上传仅内部

Postgres、PgBouncer 与 Redis 绝不对主机发布。nginx 默认终止明文 HTTP——请在 docker/nginx/ 加入 443 server block 与证书,或用你自己的反向代理或负载均衡器置于技术栈之前。

上游生产文件没有映射 ENVIRONMENT、CORS/代理控制、指标控制、多项运行时限制、Admin 门户 URL 或信用扣减 WAL。只有 Compose 文件引用的 .env 值才会进入容器。执行下方任一命令前,先创建必需的生产覆盖文件;只用基础生产文件会让 Gateway 采用 development 默认值。

起栈:

docker compose \
  -f docker-compose.prod.yml \
  -f docker-compose.production-overrides.yml \
  --env-file .env up -d --build

横向扩展

网关服务没有固定的容器名,且位于 nginx 之后,因此你可以运行多个副本。用 Compose 扩容或缩容:

# 运行 4 个网关副本
docker compose \
  -f docker-compose.prod.yml \
  -f docker-compose.production-overrides.yml \
  --env-file .env up -d --scale gateway=4

由于所有共享状态都存于 Redis 与 Postgres,增加副本是安全的:速率限制、配额、冷却与幂等都是集群级的。每个副本运行 GRANIAN_WORKERS 个 worker 进程(默认 8);按主机 CPU 调节每副本的 worker 数。

容量规划

吞吐量在很大程度上取决于你的上游供应商时延、硬件、模型与载荷大小——务必测量你自己的工作负载。以下是来自单台测试主机内部基准测试的粗略参考:

  • 一个有用的规划量级是:轻量工作负载下每个网关副本约 ~500 请求/秒
  • 在一次内部基准测试中,架构在 scale=4以零服务端错误持续承载 ~2,151 RPS,且随副本增加路由时延保持有界。

这些是在受限测试台上的基准观测,而非保证。请增加副本,并针对你真实的流量与供应商重新测量,同时关注下文的指标。

可观测性

生产可观测性使用由你运维、且能从生产网络到达的基础设施。Gateway 提供带认证的 Prometheus 格式指标,并可导出 OTLP/HTTP 追踪。

指标

Gateway 位于公开 nginx 之后时,在 .env 设置强令牌,并让 CIDR 绕过保持为空:

GATEWAY_METRICS_TOKEN=<metrics-token>
GATEWAY_METRICS_ALLOWED_CIDRS=

通过生产覆盖文件应用设置,再让现有的 Prometheus 兼容抓取器访问公开 HTTPS 端点:

docker compose \
  -f docker-compose.prod.yml \
  -f docker-compose.production-overrides.yml \
  --env-file .env up -d gateway nginx
scrape_configs:
  - job_name: cordy-gateway
    scheme: https
    metrics_path: /metrics/prometheus
    authorization:
      type: Bearer
      credentials: <metrics-token>
    static_configs:
      - targets: [gateway.example.com]

CIDR 检查使用直接 socket 对端。端点位于公开 nginx 后方时,允许 nginx 或其网络会在令牌校验前放行它代理的所有公共请求。只有抓取器通过直接、隔离的受信路径连接时,才使用 GATEWAY_METRICS_ALLOWED_CIDRS

有用的指标族包括 gateway_requestsgateway_requests_errorgateway_tokensgateway_cost_usdgateway_failover_success_rategateway_routing_overhead_msgateway_provider_circuit_breaker_state

追踪(OpenTelemetry)

配置.env 中设置完整 OTLP/HTTP trace URL 与请求头,再应用生产覆盖文件。collector 主机名必须能从 Gateway 容器解析;其 HTTPS 证书必须受容器信任;网络策略必须允许向其发送流量。

随附配置的定位

docker-compose.monitoring.ymldocker-compose.tracing.ymldocker-compose.observability.yml 都是开发/参考配置。监控服务加入外部开发网络,而生产 nginx 与 Gateway 加入 cordy-link-prod-network;tracing 与 observability collector 同样不与生产 Gateway 共享网络。observability 配置还带 CHANGEME 默认值。这些文件可作为源码示例,但不是生产叠加文件;除非另行设计并验证网络、密钥、存储与访问控制部署,否则不要把它们加入生产命令。

信用扣减 WAL

生产覆盖文件把具名卷 gateway_wal 挂载到 /var/lib/cordy,并把 Redis 失败备份写入 /var/lib/cordy/credit-consume.jsonl。这样容器重建后仍保留追加式证据。随附镜像以 root 运行并可写入挂载目录;若重新分发的镜像改用自定义 UID,必须在承载流量前创建目录并授予该 UID 写权限。

该 WAL 是软失败计费记录,不是带自动消费者的队列。Redis 拒绝信用扣减缓冲写入时,请求仍完成,成本则追加到文件;追加也失败时,Gateway 会计数一笔少扣款。仓库没有自动重放工具;请按运维说明人工保留与核对 WAL 记录。

备份与升级

第二天运维以包裹 compose 技术栈的 make 目标提供:

任务命令作用
备份make backup逻辑 pg_dumpBACKUP_DIR(脚本默认 ./backups;生产模板为 /var/backups/cordy;保留 BACKUP_RETENTION)。
灾备演练make dr-drill备份、还原到一个一次性数据库并验证——RTO/RPO 代理。
升级预检make preflight升级前的只读检查。
升级make upgrade预检 → 备份 → 迁移 → 验证。用 DRY_RUN=1 预览。
升级回滚make upgrade-rollback BACKUP=…从升级备份还原数据库。
健康自检make health-check客户侧检查 Postgres、Redis、网关与备份。
验收检查make acceptance-check运行部署验收清单并输出报告。

数据库迁移由 Admin 服务拥有,并在 Admin 启动时自动运行;升级会作为 make upgrade 的一部分应用新迁移。

Kubernetes:仅供参考

k8s/ 下的 Kubernetes 清单仅供参考且未经验证。它们未经端到端运行,不是受支持的部署路径。生产环境请使用 docker-compose.prod.yml

若你为集群改编这些清单,请将其视为起点并自行验证完整路径——数据库接线(DB_*,而不仅是 DATABASE_URL)、Ingress 请求体大小限制、密钥与迁移。kubectl --dry-run=client 只检查 YAML 语法;它不证明服务能启动或能处理流量。

运维清单

  • 在 nginx(或外层代理)终止 TLS,并设置 DJANGO_SECURE_SSL_REDIRECT=True
  • 在 Admin 与 Gateway 上一致地设置 CHANNEL_ENCRYPTION_KEYS,并存放于密钥管理系统。
  • 每次创建、重建或扩容都应用 docker-compose.production-overrides.yml
  • Gateway 位于公开 nginx 后方时,用 bearer 令牌保护 /metrics/prometheus;除非抓取路径直接且隔离,否则让 CIDR 绕过保持为空。
  • 若浏览器会调用网关,显式设置 CLIENT_CORS_ORIGINS;生产环境绝不使用 *
  • 上线前配置并测试备份;就绪后启用 WAL 归档/PITR 并设置 REQUIRE_PITR=1
  • 验证 /var/lib/cordy 可写并保留 gateway_wal 卷;数据库 WAL/PITR 与信用扣减 JSONL WAL 解决不同的恢复问题。
  • 把网关副本扩展到你实测的吞吐量,并关注故障转移与错误指标。

后续步骤

  • 配置——此处引用的每个变量。
  • 运维——分步健康、排查、备份、恢复与升级命令。
  • 安全——信任模型与加固。