package db import ( "context" "fmt" "time" "github.com/jackc/pgx/v5/pgxpool" ) // 默认连接池配置:10–50 用户私部署量级够用;超出后再按实际负载调整。 const ( defaultMaxConns = 20 defaultMinConns = 2 defaultMaxConnLifetime = time.Hour defaultPingTimeout = 5 * time.Second defaultHealthTimeout = time.Second ) // Pool 是 pgxpool.Pool 的类型别名,外部代码可直接以 db.Pool 表达连接池类型, // 同时保留 pgx 原生方法(Acquire/Exec/Query/...)。 type Pool = pgxpool.Pool // NewPool 根据 dsn 构建 Postgres 连接池,并在返回前用 5s 超时的 Ping 做健康验证。 // 失败时关闭已创建的池并返回错误,避免泄露资源。 func NewPool(ctx context.Context, dsn string) (*Pool, error) { cfg, err := pgxpool.ParseConfig(dsn) if err != nil { return nil, fmt.Errorf("parse dsn: %w", err) } cfg.MaxConns = defaultMaxConns cfg.MinConns = defaultMinConns cfg.MaxConnLifetime = defaultMaxConnLifetime pool, err := pgxpool.NewWithConfig(ctx, cfg) if err != nil { return nil, fmt.Errorf("new pool: %w", err) } pingCtx, cancel := context.WithTimeout(ctx, defaultPingTimeout) defer cancel() if err := pool.Ping(pingCtx); err != nil { pool.Close() return nil, fmt.Errorf("ping: %w", err) } return pool, nil } // HealthCheck 用 1s 超时探测数据库连通性,供 healthz/readyz 等探针调用。 func HealthCheck(ctx context.Context, pool *Pool) error { c, cancel := context.WithTimeout(ctx, defaultHealthTimeout) defer cancel() return pool.Ping(c) }