# 数据库连接池性能优化指南 ## 📊 概述 数据库连接池是提升应用性能的关键。通过复用连接,避免频繁创建/关闭连接的开销。 --- ## 🔧 连接池配置 ### 基本配置 ```python from packages.adapters.postgres.connection_pool import db_pool # 初始化连接池(应用启动时) db_pool.initialize( connection_string="postgresql://user:pass@localhost:5432/db", minconn=1, # 最小连接数 maxconn=10, # 最大连接数 ) ``` ### 推荐配置 **开发环境:** - `minconn=1` - `maxconn=5` **生产环境(单实例):** - `minconn=5` - `maxconn=20` **生产环境(多实例):** ``` maxconn = (PostgreSQL max_connections - 预留) / 实例数 例如:(100 - 10) / 4 = 22.5 ≈ 20 ``` --- ## 📝 使用方法 ### 方式 1: 上下文管理器(推荐) ```python from packages.adapters.postgres.connection_pool import PooledConnection def find_user(user_id: str): with PooledConnection() as conn: with conn.cursor() as cur: cur.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cur.fetchone() # 连接自动归还到池中 ``` ### 方式 2: Repository 中使用 ```python class PostgresUserRepository: def find_by_id(self, user_id: str): with PooledConnection() as conn: with conn.cursor() as cur: cur.execute("SELECT * FROM users WHERE id = %s", (user_id,)) row = cur.fetchone() return self._row_to_user(row) if row else None ``` --- ## ⚡ 性能对比 ### 不使用连接池 ``` 创建连接: ~50ms 执行查询: ~10ms 关闭连接: ~10ms 总耗时: ~70ms ``` ### 使用连接池 ``` 获取连接: ~1ms 执行查询: ~10ms 归还连接: ~1ms 总耗时: ~12ms ``` **性能提升: 5-6 倍** 🚀 --- ## 🔍 监控连接池 ### 添加监控指标 ```python def get_pool_stats(): """获取连接池统计信息""" return { "active_connections": db_pool._pool._used, "idle_connections": db_pool._pool._pool.qsize(), "max_connections": db_pool._pool.maxconn, } ``` ### 日志记录 ```python import logging logger = logging.getLogger(__name__) def log_pool_stats(): stats = get_pool_stats() logger.info(f"Connection pool stats: {stats}") ``` --- ## ⚠️ 注意事项 ### 1. 连接泄漏 **错误示例:** ```python # ❌ 连接没有归还 conn = db_pool.get_connection() cur = conn.cursor() cur.execute("SELECT * FROM users") # 忘记 put_connection() ``` **正确示例:** ```python # ✅ 使用上下文管理器自动归还 with PooledConnection() as conn: with conn.cursor() as cur: cur.execute("SELECT * FROM users") ``` ### 2. 连接池耗尽 症状: - 应用挂起 - 超时错误 - `PoolError: connection pool exhausted` 解决: - 增加 `maxconn` - 检查连接泄漏 - 优化慢查询 ### 3. 长时间持有连接 **错误示例:** ```python # ❌ 在循环中持有连接 with PooledConnection() as conn: for i in range(10000): process_data(i) # 耗时操作 save_to_db(conn, i) ``` **正确示例:** ```python # ✅ 每次操作单独获取连接 for i in range(10000): process_data(i) with PooledConnection() as conn: save_to_db(conn, i) ``` --- ## 🚀 应用启动配置 ### FastAPI 启动事件 ```python from fastapi import FastAPI from packages.adapters.postgres.connection_pool import db_pool from apps.api.app.config import settings app = FastAPI() @app.on_event("startup") async def startup(): """应用启动时初始化连接池""" if not settings.USE_IN_MEMORY_DB: db_pool.initialize( connection_string=settings.DATABASE_URL, minconn=5, maxconn=20, ) @app.on_event("shutdown") async def shutdown(): """应用关闭时关闭所有连接""" db_pool.close_all() ``` --- ## 📈 容量规划 ### 计算公式 ``` 每个实例的最大连接数 = (CPU 核心数 * 2) + 有效磁盘数 ``` 例如: - 4 核 CPU,1 块磁盘:`4 * 2 + 1 = 9` - 8 核 CPU,2 块磁盘:`8 * 2 + 2 = 18` ### PostgreSQL 配置 ```sql -- 查看当前最大连接数 SHOW max_connections; -- 修改最大连接数(需要重启) -- postgresql.conf max_connections = 100 -- 为超级用户预留连接 superuser_reserved_connections = 3 ``` --- ## 🧪 测试连接池 ```python import pytest from packages.adapters.postgres.connection_pool import db_pool, PooledConnection def test_connection_pool(): """测试连接池基本功能""" # 初始化 db_pool.initialize("postgresql://test:test@localhost/test", minconn=1, maxconn=5) # 获取连接 with PooledConnection() as conn: assert conn is not None with conn.cursor() as cur: cur.execute("SELECT 1") assert cur.fetchone() == {'?column?': 1} # 清理 db_pool.close_all() ``` --- ## 🔗 相关资源 - [psycopg2 连接池文档](https://www.psycopg.org/docs/pool.html) - [PostgreSQL 连接管理](https://www.postgresql.org/docs/current/runtime-config-connection.html) - [数据库连接池最佳实践](https://wiki.postgresql.org/wiki/Number_Of_Database_Connections) --- **最后更新:** 2026-06-17