django 数据库连接模块解析及简单长连接改造方法


Posted in Python onAugust 29, 2019

工作中纯服务端的项目用到了线程池和django的ORM部分。django 的数据库连接在每一个线程中开启一份,并在查询完毕后自动关闭连接。

线程池处理任务时,正常使用的连接中不会被关闭,但由于数据库端有最长连接时间的限制(默认为8小时),在超时后会发生InterfaceError: (0, '')(连接关闭后使用连接/游标)或Error(2006, 'MySQL server has gone away')(mysql 服务器主动关闭连接)这类错误,所以一般会在每个任务线程中调用django.db.connection.close()进行关闭操作。

但对于频繁进行数据库连接并操作数据库的业务,反复创建连接并不是好的选择,这种场景下可以考虑将连接改造为长连接。

1. django 代码的阅读笔记

django.db.__init__.py 
#对象:
connections = ConnectionHandler()
connection = DefaultConnectionProxy()
# 函数
# 重置查询记录缓存
def reset_queries(**kwargs):
 pass
# 关闭不可用或超时(如果有设置 CONN_MAX_AGE)连接
def close_old_connections(**kwargs):
 pass
# 信号
# 在请求开始或完成时自动调用相应处理函数
signals.request_started.connect(reset_queries)
signals.request_started.connect(close_old_connections)
signals.request_finished.connect(close_old_connections)

重点是connections和connection两个实例

connections 是 ConnectionHandler类

connections.all()会给出一个列表,里面的元素为DatabaseWrapper类

ConnectionHandler内置对象及连接管理:

def __init__():
 self._connections = local()

# 连接包装类里的连接是根据配置情况使用相应的连接
def __getitem__(self, alias):
 '''略'''
 db = self.databases[alias]
 backend = load_backend(db['ENGINE'])
 conn = backend.DatabaseWrapper(db, alias)
 setattr(self._connections, alias, conn)

# 返回所管理的数据库连接
# 管理方式:分数据库,线程管理连接 
def all(self):
 return [self[alias] for alias in self]

# 关闭所有数据库连接
def close_all(self):
 for alias in self:
  try:
   connection = getattr(self._connections, alias)
  except AttributeError:
   continue
  connection.close()

threading.local 是一个全局变量,local的属性是非线程共享的,也就是在每一个线程中都会有单独一个数据库连接实例创建,因为代理及包装的原因,该连接实例为对应backend里的连接(比如,pymysql.connections.Connection)。

在线程池的情况下,close_old_connections方法是不能将线程中的数据库连接关闭的。

connection是DefaultConnectionProxy类的实例,实际是DatabaseWrapper的实例 
(使用了pymysql库:import pymysql; pymysql.install_as_MySQLdb) 
DefaultConnectionProxy?>DatabaseWrapper?>pymysql.connections.Connection(根据connections的处理调用相应的数据库连接包) 
connection有几个关键方法和属性

connection.connection = '被包装的pymysql.connections.Connection实例`
connection.close_at = None if max_age is None else time.time() + max_age # 设置的连接关闭时间

connection.connect()# 获取连接
connection.cursor() # 获取游标
connection.close()# 关闭连接

2. 将数据库连接改造为长连接

max_age(CONN_MAX_AGE) 是可以在settings里面配置的。

由于多个服务共用一套配置, 所以考虑直接在程序里修改

全局变量

max_age = 7 * 3600

在线程内开始时做下判断:

if not db.connection.connection or db.connection.close_at < time.time():
 db.connection.close()
 db.connection.connect()
 db.connection.close_at = time.time() + max_age
 print "A new conn creates !"
else:
 print "Still old conn!"

这样每个线程池中的线程会循环执行任务并只使用同一个连接,并可以控制在自己需要的连接时长后更换连接。

针对线程池的情况,close_old_connections基本没啥用处, 可以跳过该处理

django.db.close_old_connections = lambda **kwargs : None

以上这篇django 数据库连接模块解析及简单长连接改造方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用XML库的方式,实现RPC通信的方法(推荐)
Jun 14 Python
Python中列表list以及list与数组array的相互转换实现方法
Sep 22 Python
详解flask表单提交的两种方式
Jul 21 Python
Python实现矩阵相乘的三种方法小结
Jul 26 Python
将Django项目部署到CentOs服务器中
Oct 18 Python
python实现停车管理系统
Nov 30 Python
python遍历文件目录、批量处理同类文件
Aug 31 Python
解决django FileFIELD的编码问题
Mar 30 Python
Python包和模块的分发详细介绍
Jun 19 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 Python
python字符串常规操作大全
May 02 Python
python scipy 稀疏矩阵的使用说明
May 26 Python
解决Django连接db遇到的问题
Aug 29 #Python
Python pandas实现excel工作表合并功能详解
Aug 29 #Python
python openCV获取人脸部分并存储功能
Aug 28 #Python
python lambda表达式在sort函数中的使用详解
Aug 28 #Python
python实现微信小程序用户登录、模板推送
Aug 28 #Python
使用Python脚本zabbix自定义key监控oracle连接状态
Aug 28 #Python
django删除表重建的实现方法
Aug 28 #Python
You might like
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
使用Apache的rewrite技术
2006/06/22 PHP
解决phpmyadmin 乱码,支持gb2312和utf-8
2006/11/20 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
解析javascript 数组以及json元素的添加删除
2013/06/26 Javascript
JS操作Cookie写入和读取实例代码
2013/10/20 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
微信JSSDK上传图片
2015/08/23 Javascript
ArtEditor富文本编辑器增加表单提交功能
2016/04/18 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
javascript计算对象长度的方法
2017/10/25 Javascript
ng-zorro-antd 入门初体验
2018/12/03 Javascript
详解Vue基于vue-quill-editor富文本编辑器使用心得
2019/01/03 Javascript
详解Vue调用手机相机和相册以及上传
2019/05/05 Javascript
openLayer4实现动态改变标注图标
2020/08/17 Javascript
python通过ssh-powershell监控windows的方法
2015/06/02 Python
python制作爬虫爬取京东商品评论教程
2016/12/16 Python
Python中index()和seek()的用法(详解)
2017/04/27 Python
梯度下降法介绍及利用Python实现的方法示例
2017/07/12 Python
Django开发中复选框用法示例
2018/03/20 Python
基于python神经卷积网络的人脸识别
2018/05/24 Python
使用python3实现操作串口详解
2019/01/01 Python
纯CSS3实现的8种Loading动画效果
2014/07/05 HTML / CSS
Mistine官方海外旗舰店:泰国国民彩妆品牌
2016/12/28 全球购物
Lookfantastic挪威官网:英国知名美妆购物网站
2017/07/26 全球购物
标签和贴纸印刷:Lightning Labels
2018/03/22 全球购物
事业单位个人应聘自荐信
2013/09/21 职场文书
竞选班长的演讲稿
2014/04/24 职场文书
小班上学期评语
2014/05/05 职场文书
师德师风主题教育活动总结
2015/05/07 职场文书
护士旷工检讨书
2015/08/15 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery
Django一小时写出账号密码管理系统
2021/04/29 Python
Spring Boot 实现 WebSocket
2022/04/30 Java/Android