Django 原生 ORM 不支持直接的数据库连接池配置,生产环境通常通过设置 CONN_MAX_AGE 启用持久连接,或配合 PgBouncer、ProxySQL 等中间件实现连接池。适用高并发场景,风险在于配置不当可能导致数据库连接数耗尽或事务状态异常。
先说结论:Django 生产环境数据库连接优化首选持久连接配置,高并发场景需引入外部连接池中间件。
- 适合:Django 部署在 Gunicorn/uWSGI 等多进程环境且数据库连接成为瓶颈时
- 先准备:确认数据库服务器允许的最大连接数及当前负载情况
- 验收:通过数据库监控工具观察活跃连接数波动及请求延迟变化
快速处理思路
优先在 settings.py 中启用持久连接,若并发极高再部署 PgBouncer。
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'CONN_MAX_AGE': 600,
}
}为什么会这样
Django 默认每次请求结束关闭连接,高频请求下握手开销大。
Django 的数据库连接生命周期通常绑定于单个请求,请求结束即断开。在高并发场景下,频繁建立和断开 TCP 连接及数据库握手会消耗 CPU 和网络资源。引入连接池或持久连接是为了复用已建立的连接,减少握手开销。
分步处理
第一步配置 Django 持久连接,第二步评估是否引入外部池化中间件,第三步调整数据库最大连接数限制。
1. 修改 settings.py,设置 CONN_MAX_AGE 为大于 0 的整数,单位秒。
2. 若使用 PostgreSQL,安装 PgBouncer 并配置 pool_mode 为 transaction 或 session。
3. 检查数据库配置文件(如 postgresql.conf 或 my.cnf),确保 max_connections 大于应用进程数乘以池大小。
怎么验证是否生效
通过数据库系统表查询当前活跃连接数,确认连接未被频繁重置。
PostgreSQL 可查询 pg_stat_activity 表,MySQL 可执行 SHOW PROCESSLIST 命令。观察在持续请求期间,连接数是否保持稳定而非随请求波动剧烈。同时监控应用日志,确认没有出现数据库连接超时错误。
常见坑
事务隔离级别冲突和长事务占用连接是主要风险点。
1. 使用 PgBouncer 的 transaction 模式时,某些 Django 功能如 set_session 可能失效。
2. 持久连接可能在数据库重启后失效,需确保 Django 配置有重连机制。
3. 连接数设置过大可能导致数据库内存溢出,需根据服务器内存计算。
常见问题
Django 原生支持连接池吗?
Django 原生 ORM 不提供内置连接池,需依靠驱动或中间件。
CONN_MAX_AGE 和连接池有什么区别?
CONN_MAX_AGE 是持久连接,连接池方案并发能力更强。
MySQL 需要配置连接池吗?
MySQL 同样受益,可使用 ProxySQL 或调整 wait_timeout 配合持久连接。
参考来源
1. Django Documentation - Database optimization: https://docs.djangoproject.com/en/stable/topics/db/optimization/#persistent-connections
2. PgBouncer Documentation: https://www.pgbouncer.org/