Go语言中的数据库连接池:原理与优化
Go语言中的数据库连接池:原理与优化
写了十几年代码的Go后端老兵。今天聊聊数据库连接池,这个后端开发必须掌握的技术。
一、为什么需要连接池
数据库连接是昂贵的资源:
- TCP连接建立需要时间
- 数据库有最大连接数限制
- 频繁创建销毁连接影响性能
// 不好的做法:每次查询都创建连接 db, _ := sql.Open("postgres", dsn) defer db.Close() rows, _ := db.Query("SELECT * FROM users") // 好的做法:使用连接池 db, _ := sql.Open("postgres", dsn) defer db.Close() // db会被复用二、连接池配置
db, _ := sql.Open("postgres", dsn) // 连接池配置 db.SetMaxOpenConns(25) // 最大打开连接数 db.SetMaxIdleConns(10) // 最大空闲连接数 db.SetConnMaxLifetime(5 * time.Minute) // 连接最大生命周期 db.SetConnMaxIdleTime(10 * time.Minute) // 空闲连接最大存活时间三、连接池监控
// 获取连接池统计信息 stats := db.Stats() fmt.Printf("Open Connections: %d\n", stats.OpenConnections) fmt.Printf("In Use: %d\n", stats.InUse) fmt.Printf("Idle: %d\n", stats.Idle) fmt.Printf("Wait Count: %d\n", stats.WaitCount) fmt.Printf("Wait Duration: %v\n", stats.WaitDuration)四、最佳实践
1. 连接池大小设置
// 根据CPU核心数和数据库性能调整 maxConns := runtime.NumCPU() * 4 db.SetMaxOpenConns(maxConns) db.SetMaxIdleConns(maxConns / 2)2. 连接健康检查
// 定期ping检查连接健康 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := db.PingContext(ctx); err != nil { log.Printf("Database ping failed: %v", err) }五、总结
连接池是数据库访问的基石:
- 合理配置连接池大小
- 监控连接池状态
- 定期检查连接健康
记住:能跑就行,别折腾。但连接池配置一定要合理。
