连接池
问题
Rust 中如何管理数据库连接池?
答案
SQLx 内置连接池
SQLx 自带连接池,是最简单的方案:
use sqlx::postgres::PgPoolOptions;
let pool = PgPoolOptions::new()
.max_connections(20) // 最大连接数
.min_connections(5) // 最小空闲连接
.acquire_timeout(Duration::from_secs(5)) // 获取连接超时
.idle_timeout(Duration::from_secs(600)) // 空闲连接超时
.max_lifetime(Duration::from_secs(1800)) // 连接最大生命周期
.connect(&database_url)
.await?;
独立连接池(deadpool / bb8)
用于非 SQLx 场景或需要更多控制的场景:
// deadpool-postgres 示例
use deadpool_postgres::{Config, Runtime, Pool};
use tokio_postgres::NoTls;
let mut cfg = Config::new();
cfg.host = Some("localhost".to_string());
cfg.dbname = Some("mydb".to_string());
cfg.user = Some("user".to_string());
let pool: Pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls)?;
// 从池中获取连接
let client = pool.get().await?;
let rows = client.query("SELECT * FROM users", &[]).await?;
连接池方案对比
| 方案 | 异步 | 特点 | 推荐场景 |
|---|---|---|---|
| SQLx 内置 | ✅ | 最简单,与 SQLx 无缝集成 | SQLx 用户 |
| deadpool | ✅ | 轻量,支持多种后端 | 通用异步 |
| bb8 | ✅ | 功能丰富 | 需要高级配置 |
| r2d2 | ❌ | 同步,成熟 | Diesel 用户 |
连接池参数调优
| 参数 | 建议值 | 说明 |
|---|---|---|
max_connections | CPU 核数 × 2 ~ 4 | 太大反而降低性能 |
min_connections | max 的 1/4 | 避免冷启动 |
acquire_timeout | 5s | 获取不到连接就快速失败 |
idle_timeout | 10min | 回收空闲连接 |
max_lifetime | 30min | 防止连接老化 |
常见面试问题
Q1: 为什么需要连接池?
答案:
数据库连接建立(TCP 握手 + 认证)耗时约 10-50ms。连接池预先建立并复用连接,避免每次请求都重建,显著降低延迟。同时限制最大连接数,防止数据库过载。