详解多线程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中无限元素列表的实现方法
Aug 18 Python
浅析Python3爬虫登录模拟
Feb 07 Python
Python设计模式之原型模式实例详解
Jan 18 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
Jun 13 Python
python多线程分块读取文件
Aug 29 Python
余弦相似性计算及python代码实现过程解析
Sep 18 Python
利用Python脚本批量生成SQL语句
Mar 04 Python
Python json读写方式和字典相互转化
Apr 18 Python
基于matplotlib中ion()和ioff()的使用详解
Jun 16 Python
windows支持哪个版本的python
Jul 03 Python
Django url 路由匹配过程详解
Jan 22 Python
python定义具名元组实例操作
Feb 28 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
Linux下ZendOptimizer的安装与配置方法
2007/04/12 PHP
Array of country list in PHP with Zend Framework
2011/10/17 PHP
详解PHP发送邮件知识点
2018/05/06 PHP
PHP字符串与数组处理函数用法小结
2020/01/07 PHP
JavaScript Array扩展实现代码
2009/10/14 Javascript
jquery 页面全选框实践代码
2010/04/02 Javascript
js实现简单的星级选择器提交效果适用于评论等
2013/10/18 Javascript
JavaScript函数参数使用带参数名的方式赋值传入的方法
2015/03/19 Javascript
js实现表单检测及表单提示的方法
2015/08/14 Javascript
详解JavaScript编程中正则表达式的使用
2015/10/25 Javascript
JQuery核心函数是什么及使用方法介绍
2016/05/03 Javascript
JavaScript中的原型继承基础学习教程
2016/05/06 Javascript
温习Javascript基础语法之词法结构
2016/05/31 Javascript
基于KO+BootStrap+MVC实现的分页控件代码分享
2016/11/07 Javascript
深入理解Puppeteer的入门教程和实践
2019/03/05 Javascript
详解elementUI中input框无法输入的问题
2020/04/27 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
JS使用setInterval计时器实现挑战10秒
2020/11/08 Javascript
pymongo给mongodb创建索引的简单实现方法
2015/05/06 Python
详解Python的Django框架中的中间件
2015/07/24 Python
python制作填词游戏步骤详解
2019/05/05 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
思想品德自我鉴定
2013/10/12 职场文书
制冷与电控专业应届生求职信
2013/11/11 职场文书
入团者的自我评价分享
2013/12/02 职场文书
大二学生学习个人自我评价
2014/01/19 职场文书
高中物理教学反思
2014/02/08 职场文书
2014年信访维稳工作总结
2014/12/08 职场文书
《伯牙绝弦》教学反思
2016/02/16 职场文书
Django操作cookie的实现
2021/05/26 Python
CSS实现章节添加自增序号的方法
2021/06/23 HTML / CSS
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
MIME类型中application/xml与text/xml的区别介绍
2022/01/18 HTML / CSS
Golang获取List列表元素的四种方式
2022/04/20 Golang