数据库连接与连接池
问题
什么是数据库连接池?Serverless 场景下连接管理有什么问题?
答案
为什么需要连接池
每个数据库连接需要 TCP 握手、认证、分配内存。频繁创建销毁连接开销很大。
连接池配置
connection-pool.ts
// Prisma 连接池
const prisma = new PrismaClient({
datasources: {
db: {
url: `${process.env.DATABASE_URL}?connection_limit=20&pool_timeout=10`,
},
},
});
// TypeORM 连接池
const dataSource = new DataSource({
type: 'postgres',
host: 'localhost',
port: 5432,
extra: {
max: 20, // 最大连接数
min: 5, // 最小连接数
idleTimeoutMillis: 30000, // 空闲连接超时
connectionTimeoutMillis: 5000, // 连接超时
},
});
// node-postgres 原生连接池
import { Pool } from 'pg';
const pool = new Pool({
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 5000,
});
连接池大小计算
经验公式:对于大多数应用,10-20 个连接足以处理数千 QPS。
常见误区
连接池越大越好?错。数据库总连接数有限(MySQL 默认 151),过多连接导致上下文切换开销增大,性能反而下降。
Serverless 连接问题
serverless-db.ts
// Neon Serverless Driver(HTTP/WebSocket)
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
// 无需连接池,每次都是 HTTP 请求
const users = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Prisma Accelerate(连接池代理服务)
const prisma = new PrismaClient({
datasources: {
db: { url: process.env.PRISMA_ACCELERATE_URL },
},
});
常见面试问题
Q1: 连接池满了怎么办?
答案:
- 排查:是否有连接泄漏(未释放)
- 优化:减少查询耗时,快速归还连接
- 扩容:适当增大连接池
- 降级:设置请求排队超时,超时返回错误
Q2: 连接泄漏怎么排查?
答案:
// 检查活跃连接数
// PostgreSQL
SELECT count(*) FROM pg_stat_activity;
// MySQL
SHOW PROCESSLIST;
常见原因:事务未提交/回滚、未使用 try/finally 释放连接。
Q3: Serverless 场景下的数据库选型?
答案:
| 方案 | 说明 |
|---|---|
| Neon | Serverless PostgreSQL,自动扩缩容 |
| PlanetScale | Serverless MySQL(基于 Vitess) |
| Turso | 边缘 SQLite |
| Supabase | PostgreSQL + 连接池 |
| Prisma Accelerate | 连接池代理 |
相关链接
- 数据库高可用 - 连接池与高可用
- Serverless 与边缘计算 - Serverless 架构