日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python django并发访问挂掉,解决django高并发时数据库连接量过大的问题(实现连接池的方法)...

發(fā)布時間:2025/4/5 python 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python django并发访问挂掉,解决django高并发时数据库连接量过大的问题(实现连接池的方法)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Django默認每訪問一次數(shù)據(jù)庫都會創(chuàng)建一個新的數(shù)據(jù)庫連接,執(zhí)行完數(shù)據(jù)庫操作后再關閉連接。這在高并發(fā)的場景下會導致連接數(shù)不斷增多,最終出現(xiàn)“too many connections”錯誤。

如果我們使用gunicorn的gevent模式運行項目,那么不能在項目中使用threading(多線程)模塊進行數(shù)據(jù)庫操作。因為gevent會給threading模塊動態(tài)打補丁,這會導致數(shù)據(jù)庫連接無法復用,出現(xiàn)“too many connections”錯誤。

要解決以上問題,我們需要實現(xiàn)一個數(shù)據(jù)庫的連接池。實現(xiàn)連接池的方法參考了https://yunsonbai.top/2017/07/02/gunicorn-gevent-django/,這里做了一些調(diào)優(yōu)。實現(xiàn)的步驟如下:

1. 在項目的settings.py中配置數(shù)據(jù)庫連接參數(shù),使用自定義的數(shù)據(jù)庫引擎

DATABASES = {

'default': {

'ENGINE': 'myproject.mysql', # 注意這里必須是.mysql結(jié)尾

'POOL_SIZE': 20, # 每個進程的連接池的大小,總連接數(shù)=20*總進程數(shù)

'NAME': 'test',

'USER': 'root',

'HOST': '127.0.0.1',

'PASSWORD': '******',

'STORAGE_ENGINE': 'INNODB',

'PORT': '3306',

'CHARSET': 'utf-8',

'CONN_MAX_AGE': 28790, # 比mysql默認的wait_timeout小10秒

'OPTIONS': {

'init_command': 'SET default_storage_engine=INNODB',

}

}

}

2. 在項目中增加自定義的連接池模塊

以項目的根目錄為myproject為例,新建以下兩個文件:

myproject/mysql/__init__.py

myproject/mysql/base.py

這里的文件路徑mysql/base.py是固定搭配,文件夾、文件的名稱和層級關系不能變,否則會造成django及其插件導入數(shù)據(jù)庫引擎失敗,從而自動使用默認的數(shù)據(jù)庫引擎。

__init__.py是空文件,當然也可以填充其他內(nèi)容。base.py的內(nèi)容如下:

# -*- coding: utf-8 -*-

import random

from django.core.exceptions import ImproperlyConfigured

try:

import MySQLdb as Database

except ImportError as err:

raise ImproperlyConfigured(

'Error loading MySQLdb module.\n'

'Did you install mysqlclient?'

) from err

from django.db.backends.mysql.base import *

from django.db.backends.mysql.base import DatabaseWrapper as _DatabaseWrapper

class DatabaseWrapper(_DatabaseWrapper):

def get_new_connection(self, conn_params):

pool_size = self.settings_dict.get('POOL_SIZE') or 1

return ConnectPool.instance(conn_params, pool_size).get_connection()

def _close(self):

return None # 覆蓋掉原來的close方法,查詢結(jié)束后連接不會自動關閉

class ConnectPool(object):

def __init__(self, conn_params, pool_size):

self.conn_params = conn_params

self.pool_size = pool_size

self.connects = []

# 實現(xiàn)連接池的單例

@staticmethod

def instance(conn_params, pool_size):

if not hasattr(ConnectPool, '_instance'):

ConnectPool._instance = ConnectPool(conn_params, pool_size)

return ConnectPool._instance

def get_connection(self):

if len(self.connects) < self.pool_size:

new_connect = Database.connect(**self.conn_params)

self.connects.append(new_connect)

return new_connect

index = random.randint(0, self.pool_size - 1) # 注意這里和range不一樣,要減1

try:

self.connects[index].ping()

except:

self.connects[index] = Database.connect(**self.conn_params)

return self.connects[index]

3. 調(diào)整mysql的配置

調(diào)整mysql的max_connections,使其大于項目的總連接數(shù)(連接池大小*服務進程數(shù)),修改"/etc/mysql/my.cnf",在[mysqld]配置項下設置max_connections=1000,然后重啟mysql的服務。查看配置結(jié)果的sql:

SHOW VARIABLES LIKE "max_connections";

配置settings的CONN_MAX_AGE參數(shù),使其小于數(shù)據(jù)庫的wait_timeout配置,查看wait_timeout的sql:

SHOW GLOBAL VARIABLES LIKE "%wait%";

4. 驗證結(jié)果

啟動項目后訪問幾個會與數(shù)據(jù)庫交互的頁面,然后查看連接的數(shù)量,驗證連接池的效果,查看連接數(shù)量的sql:

SHOW processlist;

《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的python django并发访问挂掉,解决django高并发时数据库连接量过大的问题(实现连接池的方法)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。