Django默认每访问一次数据库都会创建一个新的数据库连接,执行完数据库操作后再关闭连接。这在高并发的场景下会导致连接数不断增多,最终出现“too many connections”错误。

如果我们使用gunicorn的gevent模式运行项目,那么不能在项目中使用threading(多线程)模块进行数据库操作。因为gevent会给threading模块动态打补丁,这会导致数据库连接无法复用,出现“too many connections”错误。

要解决以上问题,我们需要实现一个数据库的连接池。实现连接池的方法参考了https://yunsonbai.top/2017/07/02/gunicorn-gevent-django/,这里做了一些调优。实现的步骤如下:

1. 在项目的settings.py中配置数据库连接参数,使用自定义的数据库引擎

DATABASES = {

'default': {

'ENGINE': 'myproject.mysql', # 注意这里必须是.mysql结尾

'POOL_SIZE': 20, # 每个进程的连接池的大小,总连接数=20*总进程数

'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及其插件导入数据库引擎失败,从而自动使用默认的数据库引擎。

__init__.py是空文件,当然也可以填充其他内容。base.py的内容如下:

# -*- 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方法,查询结束后连接不会自动关闭

class ConnectPool(object):

def __init__(self, conn_params, pool_size):

self.conn_params = conn_params

self.pool_size = pool_size

self.connects = []

# 实现连接池的单例

@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. 调整mysql的配置

调整mysql的max_connections,使其大于项目的总连接数(连接池大小*服务进程数),修改"/etc/mysql/my.cnf",在[mysqld]配置项下设置max_connections=1000,然后重启mysql的服务。查看配置结果的sql:

SHOW VARIABLES LIKE "max_connections";

配置settings的CONN_MAX_AGE参数,使其小于数据库的wait_timeout配置,查看wait_timeout的sql:

SHOW GLOBAL VARIABLES LIKE "%wait%";

4. 验证结果

启动项目后访问几个会与数据库交互的页面,然后查看连接的数量,验证连接池的效果,查看连接数量的sql:

SHOW processlist;

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

  1. python访问数据库如何解决高并发_怎样解决数据库高并发的问题

    怎样解决数据库高并发的问题?解决数据库高并发使用缓存式的Web应用程序架构.增加Redis缓存数据库.增加数据库索引.页面静态化.使用存储过程.MySQL主从读写分离.分表分库.负载均衡集群. 解决数 ...

  2. 解决redis高并发问题的几种思路

    解决redis高并发问题的几种思路 1:布隆过滤器 首先,布隆过滤器能解决绝大部分恶意攻击的请求,比如我们数据库中的id通常都设为自增的,是有一定范围大小的,如果有黑客恶意用数据库中没有的id一直访问 ...

  3. oracle 锁表如何解决_Java高并发解决什么方式

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究 ...

  4. 如何解决数据库高并发?

    发生数据库高并发问题主要在用户访问量增加,例如以下场景:定时秒杀活动,大范围的同一时间段的抢红包活动(支付宝的新年集字领红包等) 数据库高并发的问题本质在于:一个是慢,一个是等 而要解决慢和等可以从以 ...

  5. 解决数据库高并发的常见方案

    解决数据库高并发的常见方案: 1) 缓存式的 Web 应用程序架构: 在 Web 层和 DB(数据库)层之间加一层 cache 层,主要目的:减少数据库读取负担,提高数 据读取速度.cache 存取的 ...

  6. 互联网高并发解决方案(2)--高并发服务限流特技

    RPC和本地JAVA调用的区别 RPC远程调用:一般是可以跨平台使用的,采用Socket技术,只要语言支持socket技术就可以进行互相通信.其实就是socket+反射实现的. 本地调用:只能支持Ja ...

  7. Java高并发秒杀API(四)之高并发优化

    Java高并发秒杀API(四)之高并发优化 1. 高并发优化分析 关于并发 并发性上不去是因为当多个线程同时访问一行数据时,产生了事务,因此产生写锁,每当一个获取了事务的线程把锁释放,另一个排队线程才 ...

  8. 服务器系统怎么做高并发,QPS 高并发 如何设计一个支撑高并发大流量的系统?...

    QPS 高并发 如何设计一个支撑高并发大流量的系统? 高并发架构相关概念 什么是并发? 并发是指并发的访问,也就是某个时间点,有多少个访问同时到来: 通常如果一个系统的日PV在千万以上,有可能是一个高 ...

  9. php小程序秒抢高并发,PHP 如何设计一个高并发高可用的秒杀或抢券系统

    一个大型网站应用一般都是从最初小规模网站甚至是单机应用发展而来的,为了让系统能够支持足够大的业务量,从前端到后端也采用了各种各样技术,前端静态资源压缩整合.使用CDN.分布式SOA架构.缓存.数据库加 ...

最新文章

  1. android ble 设备扫描程序,Android应用开发Android 7.0 BLE scan 问题:程序无错但扫描不到BLE设备...
  2. 3 个重要因素,带你看透 AI 技术架构方案的可行性
  3. 业务智能 ETL 设计实施策略(转载)
  4. Shellz中awk的简单用法
  5. Django 2版本
  6. 第十三章:位图(五)
  7. Technical User Stories – What, When, and How?
  8. winform第三方控件wmp
  9. canal mysql从库_大厂如何基于binlog解决多机房同步mysql数据(一)?
  10. 获取jpg图片的x,y的分辨率dpi
  11. FPGA时序约束、时序分析(一)
  12. VSCode代码格式化自动换行问题
  13. weblogic时间问题
  14. MFC加入mysql后编译成功,在自己电脑上成功运行,当打包发送到其他电脑上报错, 缺少libcrypto-1_1-x64.dll以及缺少libssl-1_1-x64.dll问题解决方案,完美亲测
  15. Pyhton词云示例(移植-情人节专用版)
  16. 全国市场调查大赛经历分享(一)
  17. Vue.use 写多个_支付宝为16个行业写的文案,据说价值30万
  18. matlab如何生成极坐标,如何在matlab中极坐标画图
  19. LeetCode第四天--罗马数字转整数
  20. windows 环境下,编译android 版opencv-4.5.5,并添加opencv_contrib-4.5.5 扩展模块

热门文章

  1. mysql 性能查看_MySQL查询性能问题排查
  2. 滚动条滚动加载图片或则请求的实现方法
  3. JS 获取 鼠标 坐标
  4. 【python之路24】装饰器
  5. 在虚拟机下体验ubuntu(有奔头)
  6. shell getopts
  7. 打造实用的Fedora 10
  8. 量子力学 一 基础2 作用量、普朗克常量与物质波
  9. Julia程序设计2 数值类型
  10. Linux 应用编程