95992828九五至尊2

使django与数据库保持长连接

二月 21st, 2019  |  882828九五至尊手机版

        方今遇上3个很蛋疼的题材,写了1个后台管理系列,
由于是后台管理连串,所以采取频率不是很高,当django程序在闲置一段时间后,再一次打开后台系统,就变得一点也不快,然后又好了。查了诸多方面,从沙盘引擎到请求(request),再到django配置,nginx等等,都未曾意识到原因。尽管也查过是还是不是数据库的来头,但都归因于查的不够深远,没有查出所以然。

        近年来遇上1个很蛋疼的难点,写了一个后台管理种类,
由于是后台管理连串,所以利用功效不是很高,当django程序在闲置一段时间后,再度打开后台系统,就变得一点也不快,然后又好了。查了广大地点,从沙盘引擎到请求(request),再到django配置,nginx等等,都未曾意识到原因。即便也查过是否数据库的来由,但都因为查的不够深切,没有查出所以然。

882828九五至尊手机版,       
有三次在拍卖权限难题时,不断地追朔源代码,由于自家使用的是dbroute来支配权限,最终稳定到了那些db(具体目录:/usr/local/lib/python2.7/dist-packages/django/db/__init__.py),里面的代码有关于连接的,不看不精通,看了后菊花一紧。作者去!原来django每回查询的时候就连一回数据库,而且查询完结之后就马上关掉,真搞不懂笔者是怎么想的。每一回查询建贰次屡次三番不是很耗时间吗?源代码如下:

       
有一回在处理权限难点时,不断地追朔源代码,由于我使用的是dbroute来支配权限,最终一定到了那个db(具体目录:/usr/local/lib/python2.7/dist-packages/django/db/__init__.py),里面的代码有关于连接的,不看不明了,看了后菊花一紧。小编去!原来django每趟查询的时候就连一回数据库,而且查询已毕将来就当下关掉,真搞不懂小编是怎么想的。每一趟查询建1次延续不是很耗时间吗?源代码如下:

from django.conf import settings
from django.core import signals
from django.core.exceptions import ImproperlyConfigured
from django.db.utils import (ConnectionHandler, ConnectionRouter,
    load_backend, DEFAULT_DB_ALIAS, DatabaseError, IntegrityError)

__all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
    'IntegrityError', 'DEFAULT_DB_ALIAS')


if settings.DATABASES and DEFAULT_DB_ALIAS not in settings.DATABASES:
    raise ImproperlyConfigured("You must define a '%s' database" % DEFAULT_DB_ALIAS)

connections = ConnectionHandler(settings.DATABASES)

router = ConnectionRouter(settings.DATABASE_ROUTERS)

# `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
# for backend bits.

# DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
# we manually create the dictionary from the settings, passing only the
# settings that the database backends care about. Note that TIME_ZONE is used
# by the PostgreSQL backends.
# We load all these up for backwards compatibility, you should use
# connections['default'] instead.
class DefaultConnectionProxy(object):
    """
    Proxy for accessing the default DatabaseWrapper object's attributes. If you
    need to access the DatabaseWrapper object itself, use
    connections[DEFAULT_DB_ALIAS] instead.
    """
    def __getattr__(self, item):
        return getattr(connections[DEFAULT_DB_ALIAS], item)

    def __setattr__(self, name, value):
        return setattr(connections[DEFAULT_DB_ALIAS], name, value)

connection = DefaultConnectionProxy()
backend = load_backend(connection.settings_dict['ENGINE'])

# Register an event that closes the database connection
# when a Django request is finished.
def close_connection(**kwargs):
    # Avoid circular imports
    from django.db import transaction
    for conn in connections:
        # If an error happens here the connection will be left in broken
        # state. Once a good db connection is again available, the
        # connection state will be cleaned up.
        transaction.abort(conn)
        connections[conn].close()
signals.request_finished.connect(close_connection)

# Register an event that resets connection.queries
# when a Django request is started.
def reset_queries(**kwargs):
    for conn in connections.all():
        conn.queries = []
signals.request_started.connect(reset_queries)

# Register an event that rolls back the connections
# when a Django request has an exception.
def _rollback_on_exception(**kwargs):
    from django.db import transaction
    for conn in connections:
        try:
            transaction.rollback_unless_managed(using=conn)
        except DatabaseError:
            pass
signals.got_request_exception.connect(_rollback_on_exception)
 django.conf  django.core  django.core.exceptions  django.db.utils  = (, , , , ,  settings.DATABASES  DEFAULT_DB_ALIAS   ImproperlyConfigured( %==



      == load_backend(connection.settings_dict[
 close_connection(**
     django.db  conn 



 reset_queries(** conn =
 _rollback_on_exception(** django.db  conn =

发现它是接受到了1个闭馆信号后就随即关闭,其实约等于每贰遍django请求,它就接二连三二回和询问二回。网上查了下资料,有个体是那般解决的:

察觉它是吸收到了三个关闭信号后就立即关闭,其实相当于每三遍django请求,它就一而再一遍和询问一回。网上查了下资料,有私房是那样解决的:

在django项目中的__init__.py文件中参与如下代码来贯彻:

在django项目中的__init__.py文件中进入如下代码来兑现:

from django.core import signals  
from django.db import close_connection  

# 取消信号关联,实现数据库长连接  
signals.request_finished.disconnect(close_connection) 
 django.core  django.db 
signals.request_finished.disconnect(close_connection) 

它采用的法则是终极一行代码相关的Signal对象,其中还有1个disconnect方法,对应已毕裁撤信号关联。

它应用的原理是终极一行代码相关的Signal对象,其中还有3个disconnect方法,对应促成取消信号关联。

     
 作者照着他的兑现来做,发现格外,在闲置几钟头后,打开后台依旧亟待10秒左右。由于自个儿动用的是fastcgi来运作django,或许django在没有动静的时候,fastcgi就把它挂起,所以就还会去重新确立连接。若是采取supervisord来运作,估计不会。

     
 我照着她的落到实处来做,发现那么些,在闲置几时辰后,打开后台依旧亟待10秒左右。由于自家使用的是fastcgi来运转django,大概django在没有动静的时候,fastcgi就把它挂起,所以就还会去重新建立连接。假设应用supervisord来运营,估计不会。

     
 既然这一个艺术十分,那就再看一下它的源码,发现backends目录下边有mysql,oracle,postgresql_psycopg2,sqlite3等,于是采纳msql进去看一下base.py文件。发现django是一贯封装MySQLdb,每创设三个MySQLdb对象实际也就开展了一回连续。能不只怕像线程池一样,三回性创制七个MySQLdb对象呢?答案是必然的。sqlalchemy有个pool可以让数据库保持长连接,那就径直把这一个文件里的Database改成sqlalchemy的pool。当然,大家不大概暴力地修改去修改源码。因为那几个模块是用来树立数据库连接的,所以可以独立出来。其实很简单,只必要修改base.py
文件几处就行。已毕形式如下:

     
 既然这一个办法11分,那就再看一下它的源码,发现backends目录下边有mysql,oracle,postgresql_psycopg2,sqlite3等,于是采纳msql进去看一下base.py文件。发现django是一贯封装MySQLdb,每创设二个MySQLdb对象实际也就开展了三遍一连。能无法像线程池一样,1遍性成立八个MySQLdb对象呢?答案是必然的。sqlalchemy有个pool可以让数据库保持长连接,这就平昔把那几个文件里的Database改成sqlalchemy的pool。当然,大家不可以暴力地修改去修改源码。因为这么些模块是用来确立数据库连接的,所以可以独自出来。其实很简短,只须要修改base.py
文件几处就行。已毕方式如下:

       
把django/db/backends/mysql目录下的文本全部拷贝出来,放在项目的八个libs/mysql上边,然后修改base.py文件。找到

       
把django/db/backends/mysql目录下的公文全部正片出来,放在项目标2个libs/mysql上面,然后修改base.py文件。找到

try:
    import MySQLdb as Database
except ImportError as e:
    from django.core.exceptions import ImproperlyConfigured
    raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
 django.core.exceptions  ImproperlyConfigured( % e)

那段代码,在底下添加:

那段代码,在上边添加:

from sqlalchemy import pool
Database = pool.manage(Database)
 sqlalchemy = pool.manage(Database)

基本上就能够了。如果还想再修改,就找到

大抵就足以了。借使还想再修改,就找到

self.connection = Database.connect(**kwargs)
self.connection = Database.connect(**kwargs)

把它注释掉,添加

把它注释掉,添加

            self.connection = Database.connect(
                  host=kwargs.get('host', '127.0.0.1'),
                  port=kwargs.get('port', 3306),
                  user=kwargs['user'],
                  db=kwargs['db'],
                  passwd=kwargs['passwd'],
                  use_unicode=kwargs['use_unicode'],
                  charset='utf8'
              )
            self.connection ==kwargs.get(, =kwargs.get(, 3306=kwargs[=kwargs[=kwargs[=kwargs[=

再修改一下settings.py的数据库配置,把django.db.backends.mysql改为libs.mysql。至此,世界美好了许多。如若精子上脑,可以运动至:来撸吧**,你会发现世界更美好。**

再修改一下settings.py的数据库配置,把django.db.backends.mysql改为libs.mysql。至此,世界美好了诸多。假如精子上脑,可以运动至:来撸吧**

http://www.bkjia.com/Pythonjc/738571.htmlwww.bkjia.comtruehttp://www.bkjia.com/Pythonjc/738571.htmlTechArticle最近遇到一个很蛋疼的问题,写了一个后台管理系统,
由于是后台管理种类,所以使用频率不是很高,当django程序在闲置一段时间后,再一次…

相关文章

Your Comments

近期评论

    功能


    网站地图xml地图