Files
sub2api-cn-relay-manager/docs/PRODUCTION_STABILITY_BASELINE.md
2026-06-04 20:00:03 +08:00

8.2 KiB
Raw Blame History

生产稳定基线

日期2026-06-04 适用环境:sub.tksea.top / remote43

目标

这份文档固定当前线上生产入口,防止临时验收栈、历史 patched host 或旧用户 key 被误当成生产真相。

生产稳定判断只看当前生产栈。历史 artifact、旧 OpenClaw profile、旧 key、旧端口只能作为迁移线索不能作为生产健康结论。

remote43 只应长期保留一套生产宿主。生产宿主同时承担生产流量和受控 smoke 测试;临时宿主只能用于短期验收,验收结束后必须清理或停止,不能长期留作备用生产入口。

当前生产固定点

层级 固定值 说明
公网数据面 https://sub.tksea.top/v1 OpenAI-compatible 用户调用入口
公网 Portal https://sub.tksea.top/portal/ 用户态静态 portal
公网管理代理 https://sub.tksea.top/portal-admin-api/ 反代到 CRM 控制面
生产宿主 127.0.0.1:8080 sub2api 主容器
生产 CRM 127.0.0.1:18190 crm-only-20260602_18190
生产宿主容器 sub2api 当前主数据面容器
生产宿主数据库 sub2api-postgres 当前主宿主 PostgreSQL
生产宿主 Redis sub2api-redis 当前主宿主 Redis
生产 CRM 二进制 /home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager-server 控制面进程
生产 CRM 数据库 /home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager.db 控制面 SQLite

Nginx 基线

/etc/nginx/sites-available/tksea 必须满足:

location /portal/ {
    alias /var/www/sub2api-portal/;
    index index.html;
    try_files $uri $uri/ /portal/index.html;
}

location /portal-proxy/ {
    proxy_pass http://127.0.0.1:8080/;
}

location /portal-admin-api/ {
    proxy_pass http://127.0.0.1:18190/;
}

location /kimi/ {
    proxy_pass http://127.0.0.1:8080/;
}

location /kimi-v1/ {
    proxy_pass http://127.0.0.1:8080/v1/;
}

location / {
    proxy_pass http://127.0.0.1:8080;
}

公网生产入口不得指向:

127.0.0.1:18169
127.0.0.1:18173
127.0.0.1:18191
127.0.0.1:18192
127.0.0.1:18193

这些端口属于历史 patched stack、route lab 或验证栈。它们可以用于验收,但不能接管 sub.tksea.top 的生产入口。

健康判定

无密钥健康检查

无密钥请求 /v1/models 返回 401 API_KEY_REQUIRED 是健康信号。它证明公网请求已经到达生产宿主,而不是 nginx 死 upstream。

curl -sS -i https://sub.tksea.top/v1/models

预期:

HTTP/2 401
API_KEY_REQUIRED

如果返回 502 Bad Gateway,优先检查 nginx upstream 是否又指回旧端口。

管理代理健康检查:

curl -fsS https://sub.tksea.top/portal-admin-api/healthz

预期:

ok

Portal 静态入口检查:

curl -fsS -I https://sub.tksea.top/portal/

预期:HTTP/2 200

真实用户 smoke

生产 smoke 必须使用当前生产宿主数据库里的 active key。旧 OpenClaw profile 中保存的 key 可能来自旧宿主或旧分组,不能作为生产健康依据。

最低通过标准:

  1. active key 请求 https://sub.tksea.top/v1/models 返回 200。
  2. 模型列表包含 gpt-5.4gpt-5.4-mini
  3. 同一个 key 请求 gpt-5.4 completionprompt 为 reply with pong only,返回 pong
  4. 同一个 key 请求 gpt-5.4-mini completionprompt 为 reply with pong only,返回 pong

2026-06-04 修复后已验证:

gpt-5.4      -> HTTP 200, text='pong'
gpt-5.4-mini -> HTTP 200, text='pong'

当前生产绑定基线

OpenAI 中转 self-service 链路必须保持:

channel 1 -> group 3
api key 11 -> group 3
account 7 -> group 3

account 7 同时服务 subscription 分组:

account 7 -> group 4

2026-06-04 的修复补齐了:

account 7 -> group 3

没有这条绑定时,/v1/models 仍可能返回 200/v1/chat/completions 会失败:

account_select_failed: no available accounts

验收栈隔离规则

验收脚本可以创建临时 host、临时 group、临时 account、临时 key 和临时 CRM但不得修改生产公网入口。

下列对象不能作为生产入口:

crm-verify-*
route-lab-*
sub2api-kimi-patched-*
sub2api-patched-*
remote43-kimi-patched-auto2-18169
proxy-real-host-1780026133

这些对象只用于复现、导入验收或历史 artifact 对照。它们的 PASS 不能替代当前生产 smoke。

临时宿主生命周期

remote43 的默认运行策略是“单生产宿主”。除当前生产宿主外,其他 host、CRM、Postgres、Redis、route lab 或 patched stack 都视为临时资源。

临时资源创建时必须满足:

  1. 不接管 sub.tksea.top 的公网数据面。
  2. 不修改生产 Nginx 的 //v1/portal-proxy/portal-admin-api upstream。
  3. 使用独立端口、独立容器名、独立数据库或独立 SQLite。
  4. artifact 记录创建原因、端口、容器名和预期清理时间。

临时资源用完后必须执行清理。最低要求:

  1. 停止临时 host / CRM 进程或容器。
  2. 停止临时 Postgres / Redis 容器,除非同一验收批次还在使用。
  3. 删除或归档临时 SSH tunnel、临时 env 文件和临时 bootstrap 文件。
  4. 确认 sudo nginx -T 不引用临时端口。
  5. 重新跑生产 smoke确认生产宿主仍可用。

允许保留的长期资源只有当前生产基线列出的生产宿主、生产 CRM、生产数据库和生产 Redis。

如果确实需要保留某个临时栈用于复现,必须显式标注为 do-not-route-public,并保证它不被 Nginx 或 OpenClaw production profile 使用。

清理后检查:

sudo docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
ss -ltnp
sudo nginx -T | grep -nE '18169|18173|18191|18192|18193|proxy_pass'
curl -sS -i https://sub.tksea.top/v1/models
curl -fsS https://sub.tksea.top/portal-admin-api/healthz

/v1/models 无 key 返回 401 API_KEY_REQUIRED 才表示生产数据面仍指向当前生产宿主。

部署脚本基线

scripts/deploy/deploy_tksea_portal.sh 的默认端口必须保持:

REMOTE_HOST_PORT="${REMOTE_HOST_PORT:-8080}"
REMOTE_CRM_PORT="${REMOTE_CRM_PORT:-18190}"

deploy/tksea-portal/nginx.sub.tksea.top.conf.example 必须和线上端口一致:

/portal-proxy/     -> 127.0.0.1:8080
/portal-admin-api/ -> 127.0.0.1:18190
/kimi/             -> 127.0.0.1:8080
/kimi-v1/          -> 127.0.0.1:8080/v1/

每次部署前后都要检查:

sudo nginx -T | grep -nE 'location /v1|location /portal|location /portal-admin-api|location /kimi|proxy_pass'

部署后必须执行:

sudo nginx -t
sudo systemctl reload nginx
curl -sS -i https://sub.tksea.top/v1/models
curl -fsS https://sub.tksea.top/portal-admin-api/healthz

旧 Key 解释规则

旧用户 key 或旧 OpenClaw profile 失败,不直接等于生产宿主异常。先判断它是否属于当前生产宿主和当前分组。

常见旧 key 失败原因:

key 属于旧宿主数据库
key 未绑定 group
key 绑定的 group 没有 account
key 对应 subscription 已过期
key 保存于旧 OpenClaw profile
key 仍指向旧模型映射

判断生产健康时,优先使用当前生产数据库生成的 smoke key或当前生产 active key。

故障分层

现象 优先判断 下一步
/v1/models 无 key 返回 502 nginx upstream 或宿主端口错误 nginx -Tss -ltnp/var/log/nginx/error.log
/v1/models 无 key 返回 401 数据面入口到达宿主 继续用 active key 跑 /v1/models
active key /v1/models 返回 200但 completion 失败 group/account/channel/upstream 问题 account_groupschannel_groups、宿主日志
日志出现 no available accounts group 没有可调度 account 查并修复 account_groups
日志出现 upstream 502/503 上游 key/quota/供应商异常 查 account probe、上游直探
OpenClaw profile 返回 401但 production key curl 通过 本机 OpenClaw key 过期或不属于当前生产宿主 更新 OpenClaw profile key
remote43 上存在多套 host 临时资源未清理 保留生产宿主,停止或归档临时栈