django 数据库连接模块解析及简单长连接改造
django 数据库连接模块解析及简单长连接改造
工作中纯服务端的项目用到了线程池和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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
重点是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()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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()# 关闭连接
1
2
3
4
5
6
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!"
1
2
3
4
5
6
7
这样每个线程池中的线程会循环执行任务并只使用同一个连接,并可以控制在自己需要的连接时长后更换连接。
针对线程池的情况,close_old_connections基本没啥用处, 可以跳过该处理
django.db.close_old_connections = lambda **kwargs : None
---------------------
作者:xwl100
来源:CSDN
原文:https://blog.csdn.net/u010477231/article/details/77576357
版权声明:本文为博主原创文章,转载请附上博文链接!
django 数据库连接模块解析及简单长连接改造的更多相关文章
- 使django与数据库保持长连接
最近遇到一个很蛋疼的问题,写了一个后台管理系统, 由于是后台管理系统,所以使用频率不是很高,当django程序在闲置一段时间后,再次打开后台系统,就变得很慢,然后又好了.查了很多方面,从模板引擎到请求 ...
- 让Django支持数据库长连接(可以提高不少性能哦)
书接上回 上回我们说到:<在生产系统使用Tornado WebServer来代替FastCGI加速你的Django应用> 那么现在很流行用一些高性能的nonblock的app server ...
- 转:基于ASP.NET的Comet长连接技术解析
原文来自于: Comet技术原理 来自维基百科:Comet是一种用于web的技术,能使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流. 简单的 ...
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 异常汇总:http://www ...
- django系列1--介绍与简单原理, wsgiref模块
一.web应用框架 Web应用框架(Web application framework)是一种计算机软件框架,用来支持动态网站.网络应用程序及网络服务的开发.这种框架有助于减轻网页开发时共通性活动的工 ...
- 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析
前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:
- Comet:基于 HTTP 长连接的“服务器推”技术解析
原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...
- jsp实时显示后台批处理进度 - out分块,简单的长连接方式
这两天在实现一个批处理操作,但是想让前台实时显示后台批处理进度,本想着用复杂一些的框架可以实现异步信息调用 但是鉴于是内部管理系统,且只有一两个人用到这个功能,所以做了一个简单的长连接方式的实时响应 ...
- 基于ASP.NET的comet简单实现 http长连接,IAsyncResult
http://www.cnblogs.com/hanxianlong/archive/2010/04/27/1722018.html 我潜水很多年,今天忽然出现.很久没写过博客了,不是因为不想写,而是 ...
随机推荐
- delphi GDI+ [1]
摘抄自:万一的博客 安装头文件:http://www.cnblogs.com/del/archive/2008/06/06/1215319.html 目录 基本使用方法(绘制直线) 绘制一组直线 绘制 ...
- 灰度直方图均衡化----python实现
直方图均衡化是使用图像直方图进行对比度调整的图像处理的方法. 该方法通常会增加许多图像的整体对比度,尤其是当图像的可用数据由接近的对比度值表示时. 通过这种调整,强度可以更好地分布在直方图上. 这允许 ...
- Java中的日期、时间操作
每次在处理日期时间的时候都要打开chrome查找一番,索性自己找一下满意的记录下来. 一.时间格式 // hh表示12小时制: HH表示24小时制 SimpleDateFormat format1 = ...
- 贪心算法求解活动安排<算法分析>
一.实验内容及要求 1.要求按贪心算法原理求解问题: 2.要求手工输入s[10]及f[10],其中注意自己判断s[i]<f[i]: 3.要求显示所有活动及最优活动安排的i事件列表.二.实验步骤 ...
- mysql ab主从复制出错及解决过程
一.mysql主从服务器报错描述:Slave_IO_Running=NO,Slave_SQL_Running=YES,Last_Errno=0 mysql slave stop ; mysql sla ...
- idea导入(import)项目和打开(open)项目的区别
前言: 每次接手老项目,都得从git或svn下载下来,但是如果之前的项目不是用idea写的怎么办,可是你又习惯啦idea,那你必须把项目在idea上跑起来,那是用import还是用open呢,如何抉择 ...
- 2018/3/4 Activiti教程之流程部署篇(与Springboot整合版)二
首先我们来看下Activiti为我们自动生成的这四张用户相关的表 先看下USER表 我已经插入了一些数据,很明显,就是保存用户的信息的 看下GROUP 用户对应的分组信息 MEMBERSHIP 用户和 ...
- Codeforces908G. New Year and Original Order
给n<=10^700,问1到n中每个数在各数位排序后得到的数的和.答案膜1e9+7. 一看就是数位DP啦..然而并没有什么思路.. 可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个 ...
- list去掉重复元素
需求: 有list 里面含有重复元素,要求去掉重复元素: solution 1: >>> a [1, 2, 2, 1, 3, 4, 5, 6, 5] >>> set ...
- ip addr
ip 32 位.四个字节.IP地址分为五类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同.A.B.C三类IP地址的特征:当 ...