feat(prod): DB 连接池上限 + LLM 失败暴露为 failed(生产级并发收尾)
为高并发生产做的三项收尾(配合已有的任务/工具并发消费): 1. DB 连接池上限(pgsql.go / memory/store.go):SetMaxOpenConns(默认 25, DB_MAX_OPEN_CONNS 可调)+ MaxIdleConns 5 + ConnMaxLifetime 1h。 防高并发无限开连接打爆 PG(max_connections 默认 100)。 2. LLM 失败暴露为 failed(graph.go):board.fatalErr —— agent 模型调用出错即上抛, runGraph 中止后续节点并返回错误 → Handle 判 failed(带原因),不再静默 done-空。 可观测/可告警,生产排障必需。 压测验证(dispatcher 并发=50, 池=25, deepseek-v4-pro 推理): - 平台同一秒并发收下 40 任务,全程零 DB/连接错误,平台开销≈0(裸 LLM 1.8s vs 平台 P50 1.7s)。 - 并发 10 健康 4.7/s;20+ 延迟暴涨 = DeepSeek 开发账号并发限流(外部),非平台。 - 失败注入(错误模型名)→ 任务正确判 failed 并回传原因。 结论:平台并发机制达生产级;真实吞吐上限 = 自托管模型容量(生产 Qwen,可加卡线性扩)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
@@ -13,6 +16,26 @@ import (
|
||||
"github.com/sundynix/sundynix-shared/contract"
|
||||
)
|
||||
|
||||
// envInt 读正整数环境变量,缺省回退 def。
|
||||
func envInt(key string, def int) int {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n > 0 {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// tunePool 给连接池设上限:高并发下不至于无限开连接打爆 PG(max_connections 默认 100)。
|
||||
// 各服务默认 25,可经 DB_MAX_OPEN_CONNS / DB_MAX_IDLE_CONNS 调整。
|
||||
func tunePool(db *gorm.DB) {
|
||||
if sqlDB, err := db.DB(); err == nil {
|
||||
sqlDB.SetMaxOpenConns(envInt("DB_MAX_OPEN_CONNS", 25))
|
||||
sqlDB.SetMaxIdleConns(envInt("DB_MAX_IDLE_CONNS", 5))
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
// errStoreDisabled 表示 Postgres 处于降级(未连接)模式,写操作无法进行。
|
||||
var errStoreDisabled = errors.New("postgres store disabled")
|
||||
|
||||
@@ -36,6 +59,7 @@ func OpenPostgres(dsn string) *Postgres {
|
||||
log.Printf("[store] postgres 不可用,降级运行(不持久化): %v", err)
|
||||
return &Postgres{}
|
||||
}
|
||||
tunePool(db) // 连接池上限,防高并发打爆 PG
|
||||
// 一次性迁移:旧表用整型自增 id,与新雪花字符串 id 不兼容(AutoMigrate 不改主键类型)。
|
||||
// 备份模型密钥(唯一不可再生的数据) → 重建全部表 → 回灌模型。其余为可重建的测试数据。
|
||||
migrateLegacyIntIDs(db)
|
||||
|
||||
Reference in New Issue
Block a user