- 计费:19 个金额字段 float64→decimal.Decimal,DB 列保持 numeric(20,8) 零迁移; API 金额仍为 JSON number(MarshalJSONWithoutQuotes),前端零改动 - failover:保留时间预算,新增 OT_PROXY_FAILOVER_CAPS_NET/SERVER/RATE/QUOTA 按失败类型封顶换渠道次数(429/配额类瞬时失败时间预算形同虚设) - 预聚合:新增 usage_channel_hourlies(schema v10),记账事务内同步 upsert, 长窗口渠道统计走桶不再扫明细,spent_last_30d 改扫 usage_daily,v10 一次性回填幂等 - 守护:internal/arch_test.go 用 go/parser 强制分层依赖(fail-closed)
104 lines
5.3 KiB
Bash
104 lines
5.3 KiB
Bash
# openteam 服务配置示例 —— 复制为 .env 后修改
|
||
# 所有项均可用环境变量 OT_<KEY> 覆盖(点号转下划线,如 db.driver → OT_DB_DRIVER)
|
||
|
||
# 运行环境 development | production(仅这两个值;生产启动会做密钥断言,见下)
|
||
OT_ENV=development
|
||
OT_PORT=8080
|
||
|
||
# 数据库(开发默认 SQLite;生产切 postgres)
|
||
OT_DB_DRIVER=sqlite
|
||
OT_DB_DSN=data/openteam.db
|
||
# OT_DB_DRIVER=postgres
|
||
# OT_DB_DSN=host=localhost user=openteam password=openteam dbname=openteam port=5432 sslmode=disable
|
||
|
||
# JWT(生产必须更换为随机长字符串;OT_ENV=production 时本文件里的占位值会被启动校验拒绝)
|
||
OT_JWT_SECRET=change-me-to-a-long-random-string
|
||
OT_JWT_ACCESS_TTL=2h
|
||
OT_JWT_REFRESH_TTL=168h
|
||
# 生产必须为 true(refresh cookie 走 HTTPS;反代终止 TLS 时也要置 true)
|
||
OT_JWT_COOKIE_SECURE=false
|
||
|
||
# 注册策略:open(开放)| invite(邀请码)
|
||
OT_AUTH_REGISTRATION_MODE=open
|
||
|
||
# 渠道密钥加密主密钥(生产必须设置,32 字节以上)
|
||
OT_MASTER_KEY=change-me-master-key
|
||
|
||
# 默认上游渠道(首次启动自动创建 OpenAI 渠道)
|
||
OT_PROXY_UPSTREAM_KEY=
|
||
OT_PROXY_UPSTREAM_BASE_URL=https://api.openai.com
|
||
OT_PROXY_DEFAULT_MODEL=gpt-4o-mini
|
||
# 上游超时兜底值(渠道 timeout_ms 优先):
|
||
# 非流式 = 整段请求上限;流式 = 只约束首包,正文不限时长
|
||
OT_PROXY_TIMEOUT=300s
|
||
|
||
# /v1 请求体上限(MB):超限按客户端协议返回 413
|
||
OT_PROXY_MAX_BODY_MB=32
|
||
|
||
# 故障转移给"第二个及以后的渠道"留的时间预算(0=不限)。
|
||
# 首个渠道不受它约束——长回答本就要跑几分钟,但不能让坏渠道把客户端拖到 N×timeout。
|
||
OT_PROXY_FAILOVER_BUDGET=30s
|
||
# 按失败类型限制"换渠道"次数(0=不限):net=网络错误/超时、server=5xx、
|
||
# rate=429 限流、quota=余额/配额。429/配额类失败瞬时返回,上面的时间预算对它们
|
||
# 形同虚设,按次数封顶才有意义(如全渠道欠费时不至于把候选逐个打一遍)。
|
||
OT_PROXY_FAILOVER_CAPS_NET=4
|
||
OT_PROXY_FAILOVER_CAPS_SERVER=3
|
||
OT_PROXY_FAILOVER_CAPS_RATE=2
|
||
OT_PROXY_FAILOVER_CAPS_QUOTA=3
|
||
# 流式空闲多久补一行 SSE 注释心跳(0=关闭)。挂在 nginx/Cloudflare 后面时,
|
||
# 上游长时间不出字(长思考)会被对端的空闲超时掐掉,心跳用来续住这条流。
|
||
OT_PROXY_STREAM_HEARTBEAT=15s
|
||
# 流式在放行给客户端之前最多等内容多久(0=不限):超时未出内容就取消本次尝试、
|
||
# 换下一个渠道。上游挂起(连接正常但一直不吐字)时的兜底。
|
||
OT_PROXY_FIRST_TOKEN_WAIT=0s
|
||
# 会话亲和 TTL(0=关闭,默认 5m):同一会话粘住上次应答的渠道,命中上游的提示词
|
||
# 缓存(整段上下文每轮重发),而不是被加权随机打散后全价重算。
|
||
OT_PROXY_AFFINITY_TTL=5m
|
||
# 渠道并发满载时每个候选渠道最多排队多久(0=立刻跳过)。上游 LLM 请求本来就慢,
|
||
# 短暂排队远好于把 502 直接甩给 agent;排队仍拿不到槽时返回 503 + Retry-After。
|
||
OT_PROXY_CHANNEL_ACQUIRE_WAIT=150ms
|
||
# 鉴权缓存 TTL(0=关闭,默认 2s)。命中时省掉每个请求的两条随机读(api_keys/users),
|
||
# 实测 p50 从 535µs 降到 131µs。代价:密钥/用户被停用后最多延迟这个时间才生效
|
||
# (管理端与用户的写操作会立即清空缓存,所以实际窗口通常远小于 TTL)。
|
||
OT_PROXY_AUTH_CACHE_TTL=2s
|
||
|
||
# 渠道健康检查
|
||
OT_PROXY_HEALTH_INTERVAL=60s
|
||
OT_PROXY_HEALTH_FAIL_THRESHOLD=2
|
||
|
||
# 调试:记录管理员的原始请求与响应到请求明细(默认关闭;流式记录全部事件)
|
||
# 记录管理员请求的原始请求体/响应体到 usage_logs(调试用)。
|
||
# 原始体会截断:请求体 256 KiB、响应体 1 MiB,避免单条日志几十 MB 拖慢查询与备份。
|
||
OT_PROXY_LOG_RAW=false
|
||
|
||
# 用量明细保留天数(0=永久保留,默认)。开启后每天清理超过该天数的 usage_logs,
|
||
# 分批删除(每批 2000 行),余额流水 balance_logs 不受影响。
|
||
OT_USAGE_RETENTION_DAYS=0
|
||
|
||
# 限流(内存计数,Redis 后置):用户级每秒请求数上限(0=不限制)
|
||
OT_RATELIMIT_USER_RPS=20
|
||
# 认证端点限速(每分钟,0=不限制):登录是密码爆破面,注册是批量建号面
|
||
OT_RATELIMIT_LOGIN_IP_PER_MIN=30
|
||
OT_RATELIMIT_LOGIN_USER_PER_MIN=10
|
||
OT_RATELIMIT_REGISTER_IP_PER_MIN=5
|
||
|
||
# 跨域白名单(逗号分隔 origin)。留空 = 不输出任何 CORS 头:
|
||
# 网关自托管 web/dist 时前后端同源、vite dev 走 proxy,都不需要跨域。
|
||
# 只有把 web/ 单独部署到别的域名时才需要配。
|
||
OT_CORS_ALLOW_ORIGINS=
|
||
# 反向代理(CIDR 或 IP,逗号分隔)。配置后 gin 才信任 X-Forwarded-For 取客户端 IP,
|
||
# 上面的认证限速依赖它;直连部署留空(此时按连接源地址计数,伪造头无效)。
|
||
OT_SERVER_TRUSTED_PROXIES=
|
||
|
||
# Passkey(WebAuthn):RPID 为域名,RPOrigin 为前端来源(需 HTTPS 或 localhost)
|
||
OT_WEBAUTHN_RP_ID=localhost
|
||
OT_WEBAUTHN_RP_ORIGIN=http://localhost:5173
|
||
OT_WEBAUTHN_RP_NAME=openteam
|
||
|
||
# 初始管理员(仅首次创建生效)。非 development 环境未显式设置 OT_ADMIN_PASSWORD
|
||
# 时拒绝播种管理员;admin123 是公开默认值,生产启动校验也会拒绝它。
|
||
OT_ADMIN_USERNAME=admin
|
||
OT_ADMIN_EMAIL=admin@localhost
|
||
OT_ADMIN_PASSWORD=admin123
|
||
|