详解多线程Django程序耗尽数据库连接的问题


Posted in Python onOctober 08, 2018

Django的ORM是非常好用的,哪怕不是做Web项目也值得一用,所以网上也可以找到不少使用 Django 开发非Web项目的资料,因为除了ORM之个,命令行、配置文件等组件也非常好用。

最近用这种方式开发了一个非Web项目,而且是多线程的。有N个工作线程从DB中获取jobs,并把结果写回DB。简单来说就是这样。

项目运行一段时间后,发现数据库连接耗尽了,幸好内存大,然后一直往上调,最后连接数都上九千多一万了。耗尽连接数的时候,PostgreSQL 会出现类似这样的错误:

FATAL: remaining connection slots are reserved for non-replication superuser connections

然后就各种看文档、代码,找问题,其中艰难略下不表,最后大概是这么些个知识点:

  1. Django里的数据库连接是放在线程的 local() 实例中的。
  2. 任何时候,需要一个数据库连接的话,Django就会创建一条出来,或者用本线程已有的那条。
  3. 如果是Web项目,在请求结束的时候,Django会去关闭掉连接。是的,没有连接池。
  4. 因为我们是非Web项目,所以不存在请求结束事件,所以一直没的关闭连接。但本来这个应该也不会造成问题的,因为没关闭就一直用呗,但不知道哪里出了问题,会出现连接泄漏,所以连接数据会一直增长。

最后的解决方案是找时机主动关闭数据库连接,具体到我们项目,就是每次工作线程完成一个任务后,就把它相关的连接关掉,因为我们用的是 ThreadPoolExecutor ,所以Django很容易做到这一点。

重点代码如下:

from django.db import connections

def on_done(future):
  # 因为每一个线程都有一个 connections,所以这里可以调用 close_all(),把本线程名下的所有连接关闭。
  connections.close_all()

def main():
  # ...
  with ThreadPoolExecutor() as executor:
    while True:
      future = executor.submit(do, get_a_job())
      future.add_done_callback(on_done)

主动关闭后,数据库连接数降到与工作线程数相近,并保持稳定。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python机器学习案例教程——K最近邻算法的实现
Dec 28 Python
Python3的介绍、安装和命令行的认识(推荐)
Oct 20 Python
对Python3 * 和 ** 运算符详解
Feb 16 Python
python3.6实现学生信息管理系统
Feb 21 Python
图文详解python安装Scrapy框架步骤
May 20 Python
python爬虫 模拟登录人人网过程解析
Jul 31 Python
简单瞅瞅Python vars()内置函数的实现
Sep 27 Python
python两个_多个字典合并相加的实例代码
Dec 26 Python
Django 多对多字段的更新和插入数据实例
Mar 31 Python
详解Python IO口多路复用
Jun 17 Python
什么是Python包的循环导入
Sep 08 Python
解决hive中导入text文件遇到的坑
Apr 07 Python
JSON文件及Python对JSON文件的读写操作
Oct 07 #Python
Python实现登陆文件验证方法
Oct 06 #Python
python对日志进行处理的实例代码
Oct 06 #Python
浅析Python函数式编程
Oct 06 #Python
Python实现iOS自动化打包详解步骤
Oct 03 #Python
Python中GIL的使用详解
Oct 03 #Python
Python线程同步的实现代码
Oct 03 #Python
You might like
第六节--访问属性和方法
2006/11/16 PHP
PHP添加MySQL数据记录代码
2008/06/07 PHP
php输出表格的实现代码(修正版)
2010/12/29 PHP
php判断页面是否是微信打开的示例(微信打开网页)
2014/04/25 PHP
Yii1.1框架实现PHP极光推送消息通知功能
2018/09/06 PHP
漂亮的仿flash菜单,来自蓝色经典
2006/06/26 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
Angular6 正则表达式允许输入部分中文字符
2018/09/10 Javascript
使用express来代理服务的方法
2019/06/21 Javascript
vue 中 命名视图的用法实例详解
2019/08/14 Javascript
Vue的编码技巧与规范使用详解
2019/08/28 Javascript
javascript 内存模型实例详解
2020/04/18 Javascript
多种类型jQuery网页验证码插件代码实例
2021/01/09 jQuery
python实现爬虫统计学校BBS男女比例之多线程爬虫(二)
2015/12/31 Python
python使用xlrd与xlwt对excel的读写和格式设定
2017/01/21 Python
Python编程实现的简单神经网络算法示例
2018/01/26 Python
基于Python中求和函数sum的用法详解
2018/06/28 Python
python计算两个数的百分比方法
2018/06/29 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
Python3 pandas 操作列表实例详解
2019/09/23 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
Python图像处理库PIL的ImageEnhance模块使用介绍
2020/02/26 Python
详解Anaconda安装tensorflow报错问题解决方法
2020/11/01 Python
CSS3让登陆面板3D旋转起来
2016/05/03 HTML / CSS
蛋白质世界:Protein World
2017/11/23 全球购物
Veronica Beard官网:在酷、经典和别致之间找到了平衡
2018/01/11 全球购物
草莓网官网:StrawberryNET
2019/08/21 全球购物
如何获得EntityManager
2014/02/09 面试题
行政文员岗位职责
2013/11/08 职场文书
医学检验专业大学生求职信
2013/11/18 职场文书
给国外客户的邀请函
2014/01/30 职场文书
《尊严》教学反思
2014/02/11 职场文书
儿童生日会策划方案
2014/05/15 职场文书
个人租房协议书
2014/11/28 职场文书
家长会欢迎词
2015/01/23 职场文书