首页 > 数据库 >python web框架多进程部署下数据库连接问题

python web框架多进程部署下数据库连接问题

时间:2023-01-30 17:31:29浏览次数:45  
标签:fork web python 创建 数据库 进程 连接 连接池


python常用的web框架,诸如flask,django,在生产部署时,都会选择多进程的部署方式,选用的中间件多为uwsgi或者gunicorn。

如果项目里使用了数据库,那么就要考虑数据库连接在多进程下的一些问题,本文以mysql数据库为例。

1. 多进程下共用数据库连接

python连接mysql的客户端驱动库有很多种,例如pymysql,它们都提供了数据库连接池,连接池是多线程安全的,多进程下并不安全。

多线程的安全,是通过线程锁解决的,这非常容易做到,而多进程加锁则并不容易。

我所谓的多进程,是由主进程fork出来的子进程,如果主进程里创建了数据库连接池,随后fork出子进程,子进程在获取数据库连接时,两个子进程就有可能获得同一个数据库连接,这样就会引发问题。

一个数据库连接,本质上就是一个socket连接,建立socket连接后,得到一个打开的socket对象,当两个进程都用这同一个socket对象发送和接收数据时,就会引发异常。

不论是用uwsgi还是gunicorn,其原理都是相似的,创建出app后,fork子进程,这样做的目的是提供web服务的响应能力,work的数量需要合理配置。

对于这种部署方式,我一直都担心出现子进程共用同一个数据库连接的问题,直到最近,猛然间找到了问题的本质。

2. 避免fork前使用连接

目前所用的数据库连接驱动库,都有一个惰性连接的特性。如果你设置连接池的大小是10,那么当程序启动后,连接池并没有真的被建立,只有当程序进行一次数据库操作时,才会真的去建立连接。当连接数量不够时,才会去新建连接,如果连接池里有空闲的连接,会直接拿来使用。

因此,只要保证在创建出app以后,不使用数据库连接进行任何操作,而是等到有真实的请求到来以后再进行数据库操作即可避免多进程共用数据库连接的问题。

只要父进程没有对数据库进行操作,父进程便不会创建数据库连接池。

当请求真实到达时,已经完成了fork动作,此时的子进程,并没有从父进程那里继承数据库连接池,因为父进程自己也没有创建连接池。

请求打到某个字进程,这个子进程在进行数据库操作时创建只属于自己的数据库连接池,不会受到其他子进程的干扰。

3. 合理设置连接池大小

多进程部署模式下,如果你不开启多线程,那么一个子进程便只有一个线程,此时,你设置连接池的大小为1即可。设置的更大,也不会创建出更多的连接,因为对于单个子进程来说,有一个数据库连接就已经足够了。

为了提高响应能力,你开启线程,uwsgi和gunicorn都允许你这样做。那么你要根据线程的数量来设置连接池的大小,与其相等即可,多了也同样不起作用。


标签:fork,web,python,创建,数据库,进程,连接,连接池
From: https://blog.51cto.com/u_15948370/6027512

相关文章

  • python使用正则表达式实现字符串替换
    python的字符串提供了replace方法,可以将子串替换成其他字符串,例如下面的代码name='flask_script'name=name.replace('_','-')print(name)#flask-script替换的前提......
  • C++子线程中调用python代码
    项目需要C++调用python的算法,由于python算法比较耗时,因此采用在C++里启动workingthread来调用python脚本,python代码里含有cv2.imread()等opencv的调用,在子线程里调用会卡......
  • 【Python笔记2.1】Python Unicode字符编解码
    以下部分参考[1],这里复制了其中一部分是为了防止原文被移动或删除。概述Python中有字符串类型(str)和字节类型(byte),以及Python编码中最常见也是最顽固的两个错误:Unic......
  • 【Python笔记2.2】用zipfile解压zip包时遇到的Unicode字符编解码问题
    pythonunicode字符编解码问题参见【Python笔记2.1】python中用zipfile解压zip包网上资料一堆,这里就不多说了。下面使用【Python笔记2.1】中总结出来的字符编解码函数......
  • 【KAWAKO】python查看内存空间占用情况
    目录查看变量的内存占用查看运行内存占用查看变量的内存占用importsysc=1145.114print(sys.getsizeof(c))查看运行内存占用importpsutilmemory=psutil.vir......
  • python实用小技之数据结构
     本文大多数例子搬自pythoncookbook这里是对学习的一个总结和提炼ps:python版本为python3 1.解压序列赋值给多个变量#有一个包含N个元素的元组或者是序列,怎样将......
  • 1 web 应用模式 、2 API接口 、3 接口测试工具postman
    目录1web应用模式2API接口3接口测试工具postman1web应用模式#djangoweb框架,专门用来写web项目#之前学的,写的bbs项目,图书管理系统,用的是前后端混合开发 -后端......
  • node webkit使用默认浏览器打开连接
    我们使用nw进行软件开发,有时候需要打开连接,但是正常情况下,nw会默认使用nw打开连接,而我们需要使用默认的浏览器打开,具体流程:首先,引入nw的模块letgui=require('nw.gui');......
  • python 中异常类型总结
    异常类型:异常名称描述BaseException       所有异常的基类SystemExit          解释器请求退出KeyboardInterrupt    用户中断......
  • python实战-基于正交实验(工具:allpairs)自动生成接口异常测试用例
    实现思路1.抓取api信息(目前公司用的swagger),uri、method、params、response,解析完成后写入excle2.读取抓取完毕的api信息,处理为allpairs所需要的ordereddict3.调用allpai......