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 我潜水很多年,今天忽然出现.很久没写过博客了,不是因为不想写,而是 ...
随机推荐
- 零基础入门学习Python(27)--集合:在我的世界里,你就是唯一
知识点 集合:set set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key. 集合中的元素的三个特征: 1)确定性(元素必须可hash ...
- 理解ZAB协议
ZAB协议 介绍 1.zab协议是为分布式协调服务zookpeer专门设计的一种支持崩溃恢复的原子广播协议 2.在zookeeper中主要依赖ZAB协议来实现数据一致性,基于该协议zk实现了一种主备模 ...
- python爬虫(三)
Requests模块 这个库的标准文档有个极其幽默的地方就是它的中文翻译,我就截取个开头部分,如下图: 是不是很搞笑,在正文中还有许多,管中窥豹,可见一斑.通过我的使用,感觉Requests库的确是给 ...
- LeetCode(36)Valid Sudoku
题目 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- flash-热风焊盘的制作
计算部分: 热风焊盘的内径(ID)等于钻孔直径+20mil, 外径(OD)等于Anti-pad的直径,通常是比焊盘的直径大20mil. 开口宽度等于(OD-ID)/2+10mil,保留整数位. 如果焊 ...
- 使用mysql-proxy 快速实现mysql 集群 读写分离
目前较为常见的mysql读写分离分为两种: 1. 基于程序代码内部实现:在代码中对select操作分发到从库:其它操作由主库执行:这类方法也是目前生产环境应用最广泛,知名的如DISCUZ X2.优点是 ...
- wangEditor
wangEditor 基于javascript和css开发的 Web富文本编辑器, 轻量.简洁.易用.开源免费 http://www.wangeditor.com/index.html API htt ...
- poj 1733离散化(map)+并查集
http://blog.sina.com.cn/s/blog_803d08c00100y2yy.html #include<stdio.h> #include<iostream> ...
- POJ 2828 Buy Tickets (线段树 || 树状数组)
题目大意 一些小朋友在排队,每次来一个人,第i个人会插到第x个人的后面.权值为y.保证x∈[0,i-1]. 按照最后的队伍顺序,依次输出每个人的权值. 解题分析 好气吖.本来是在做splay练习,然后 ...
- Linux下汇编语言学习笔记34 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...