mssql-django 中的连接池

本文介绍连接池的工作原理 mssql-django 以及如何为 Django 应用程序配置连接池。

连接池的工作原理

默认情况下, mssql-django 使用 pyodbc 的内置连接池。 当 Django 关闭连接时,pyodbc 会将其返回到池,而不是关闭基础 ODBC 连接。 后续连接请求重复使用共用连接,从而减少建立新数据库连接的开销。

配置连接池

连接池通过 DATABASE_CONNECTION_POOLING 设置进行控制,该设置位于 settings.py 的模块级别(位于 DATABASES 字典之外):

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

# Set to False to disable pyodbc's connection pooling
DATABASE_CONNECTION_POOLING = False
价值 Behavior
True(默认值) 连接池已启用。 关闭的连接将返回到池。
False 连接池已禁用。 每个连接在释放时都会被完全关闭。

何时禁用连接池

请考虑在以下情况下禁用连接池:

  • 基于令牌的身份验证:使用过期的访问令牌时,共用连接可能会保留过时的令牌。
  • 调试连接问题:禁用连接池可简化故障排除,因为这样能确保每个请求都会创建一个新连接。
  • 短生命周期进程:对于只执行少量查询便退出的脚本或管理命令,连接池没有任何益处。

连接重试设置

无论连接池设置如何,都可以配置连接尝试失败时的重试行为。 有关重试和超时选项的完整列表,请参阅 配置参考

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "connection_retries": 3,
            "connection_retry_backoff_time": 10,
            "connection_timeout": 30,
        },
    },
}

Django 的 CONN_MAX_AGE

Django 还提供一个 CONN_MAX_AGE 设置,用于控制 Django 在关闭数据库连接之前保持打开状态的时间。 此设置与 pyodbc 的连接池配合使用:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "CONN_MAX_AGE": 600,  # Keep connections open for 10 minutes
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

有关详细信息 CONN_MAX_AGE,请参阅 Django 数据库设置文档

实用的起点:

  • CONN_MAX_AGE=0:最安全用于调试和短期作业。
  • CONN_MAX_AGE=600:对于许多 Web 应用来说,是个不错的默认选择。
  • CONN_MAX_AGE=3600:经过负载测试后,对于稳定的高吞吐量服务是合理的。

Note

使用 ASGI 服务器(如 Daphne 或 Uvicorn)或线程部署时,永久性连接可能会跨异步上下文泄漏。 如果你将 CONN_MAX_AGE 与 ASGI 服务器一起使用,请设置 CONN_HEALTH_CHECKS = True(Django 4.1 及更高版本),并在真实并发场景下进行测试。 有关详细信息,请参阅有关 连接管理的 Django 文档。

CONN_HEALTH_CHECKS 在重复使用之前验证共用连接。 如果 Django 检测到过时的连接,则会以透明方式打开一个新的连接。 这会增加每次请求的少量检查开销,而且对于长期运行的进程来说,通常值得启用。