使用django和sqlalchemy的连接池

django-conn-pool的Python项目详细描述


Django Conn游泳池

使用django(>;2.0.0)和sqlalchemy(>;=1.2.7)的mysql连接池。

为什么

如果设置中没有设置CONN_MAX_AGE,django将为每个请求建立一个新的mysql连接,并在请求后关闭它。

因此,如果要处理的连接太多,它将建立太多的连接,直到mysql max_connections用完为止。

然后,mysql将返回错误:ERROR 1040 (08004): Too many connections

对于一个健壮的django项目,有必要维护一个连接池。

原理

Reference: MySQL Connection Pooling with Django and SQLAlchemy

使用sqlalchemy queuepool从连接池创建mysqldb数据库get_new_connection

所以我们只需要自定义一个由连接池管理的数据库,并从连接池中获取新的连接。

pip install mysqlclient
pip install SQLAlchemy

核心代码

import MySQLdb as Database
import sqlalchemy.pool as pool
from sqlalchemy.pool import QueuePool
from django.db.backends.mysql.base import DatabaseWrapper as _DatabaseWrapper


Database = pool.manage(Database, poolclass=QueuePool, **settings.SQLALCHEMY_QUEUEPOOL)

class DatabaseWrapper(_DatabaseWrapper):

    def get_new_connection(self, conn_params):
        # return a mysql connection
        databases = settings.DATABASES
        alias = None
        for _alias in databases:
            if databases[_alias]['NAME'] == conn_params['db']:
                alias = _alias
                break
        client_flag = conn_params['client_flag']

        conn_params = databases[alias]
        return Database.connect(
            host=conn_params['HOST'],
            port=conn_params['PORT'],
            user=conn_params['USER'],
            db=conn_params['NAME'],
            passwd=conn_params['PASSWORD'],
            use_unicode=True,
            charset='utf8',
            client_flag=client_flag,
            sql_mode='STRICT_TRANS_TABLES',
        )

使用量

pip install django-conn-pool

settings.py

# http://docs.sqlalchemy.org/en/latest/core/pooling.html#sqlalchemy.pool.QueuePool
# http://docs.sqlalchemy.org/en/latest/core/pooling.html#sqlalchemy.pool.Pool.params
SQLALCHEMY_QUEUEPOOL = {
    'pool_size': 10,
    'max_overflow': 10,
    'timeout': 5,
    'recycle': 119,
}

DATABASES = {
    'default': {
        'ENGINE': 'django_conn_pool.mysql',
        'HOST': '127.0.0.1',
        'NAME': 'xxx',
        'USER': 'xxx',
        'PASSWORD': 'xxx',
        'PORT': 3306,
    },
    'other': {
        'ENGINE': 'django_conn_pool.mysql',
        'HOST': '127.0.0.1',
        'NAME': 'xxx',
        'USER': 'xxx',
        'PASSWORD': 'xxx',
        'PORT': 3306,
    },
}

测试

如果python manage.py runserver可以,现在可以使用负载测试实用程序Siege进行测试。

siege -r 2 -c 1000 -d 0 http://xxx  # siege --help

您可以将mysql进程列表计数与之前的进行比较,它应该可以工作。

顺便说一句,如果在请求过程中没有得到连接,那么应该得到一个sqlalchemy.exc.TimeoutError:异常。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何通过jamod读取控制器的输入状态?   java Back bean方法在使用两个h的单一表单时未调用:selectonemenus和command button   mockitojava中的单元测试Mock继承方法   java在不传递到构造函数的情况下,将一个类的实例使用到另一个类中的最佳方法是什么   java Spring MVC:如何通过API在Dozer的toplevel字段中允许空值?   java hibernate到MSSQL服务器的连接被拒绝:连接   java动态调用现有变量   在java中扩展多个类的泛型   java使用JNA Ptrace获取linux中外部进程的信息?   eclipse获取Java项目中所有构建错误的最快方法是什么?   java将动态数组拆分为多个数组   java安卓:将json保存到sqlite   java获取最近时间Android   java如何为多对多关联编写HQL查询?   java Docker compose for mysql和spring应用程序拒绝访问   java查找数组(如果它是另一个数组的子集)   java如何在另一个具有相同数据类型参数的泛型类(或接口)中使用泛型类(或接口),而无需强制转换   Apache POI java。lang.NoClassDefFoundError:org/apache/commons/compress/utils/InputStreamStatistics   java使用Jackson将JSON反序列化为异构元素列表   使用MapReduce实现java规范化