浅谈django url请求与数据库连接池的共享问题

但凡介绍数据库连接池的文章,都会说“数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。”

这句话虽然说得很好,但也很让人疑惑。比如,多个请求是怎样共用数据库连接池啊?

其实,数据库连接池主要是利用了程序,静态变量与静态方法的概念实现的。静态变量和静态方法,是程序运行时,就被加载到内存中的。该进程中所有对于它的访问,都是对“唯一”的它的访问。所以,才能有数据库连接池被共享的概念。

可以看到,静态变量a以及静态方法add,即使类A从未被实例化过,它们也都会被加载到内存中。

另外,在python的此次运行(一个进程)中,多次对a的操作,都是对为一个的这个a变量的操作,所以它的值是在被操作后累加的。

这个在我上面简单的例子中很好理解。那么如何理解Web应用程序(如django程序)在接到url请求时的场景呢?在多个请求时,他们是如何可以共享数据库连接池的?

我写了一个简单的例子:

Test model,使用了单例模式,它的功能是调用sqlalchemy.pool中的数据库连接池。

而views.py的index方法,则是调用Test的getinstance方法获得它的实例,同时用它的数据库连接池。

为了看得清楚,我在这个方法中增加打印了当前所属进程的pid,test和test.connpool信息。

首先要说明一点,apache在windows和linux中的运行方式不尽相同(windows是两个httpd进程,一个父进程,一个子进程,子进程里面多个线程处理请求)。在linux中,默认用prefork的方式运行。即一个父进程,多个子进程,这多个子进程负责处理web请求。

如下图所示:

然后我们尝试多次url请求(适当变化url,避免缓存);并记录结果:

http://10.67.2.21:8081/ips/
count:3,processid:20016<br/>test:<ipsapp.models.Test object at 0x7f2b1070ac50>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b1070ad10>

http://10.67.2.21:8081/ips/?user=kjsdkfjsdf&kljsdlkfjsdf
count:3,processid:20013<br/>test:<ipsapp.models.Test object at 0x7f2b107c6c10>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b107c6cd0>

http://10.67.2.21:8081/ips/?user=kjsdkfjsdf&kljsdlkfjsdf&pass=ksjdkjdf
count:3,processid:20018<br/>test:<ipsapp.models.Test object at 0x7f2b103c6c50>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b103c6d10>

http://10.67.2.21:8081/ips/?user=123u42i3u4
count:3,processid:20016<br/>test:<ipsapp.models.Test object at 0x7f2b1070ac50>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b1070ad10>

http://10.67.2.21:8081/ips/?user=123u42i3u4&tewstsjdfkjslfj
count:3,processid:20013<br/>test:<ipsapp.models.Test object at 0x7f2b107c6c10>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b107c6cd0>

http://10.67.2.21:8081/ips/?user=passwode
count:3,processid:20018<br/>test:<ipsapp.models.Test object at 0x7f2b103c6c50>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b103c6d10>

http://10.67.2.21:8081/ips/?newiusd=kjsdkjfd&kjsdkjf=ksdjflksjdlkf
count:3,processid:20016<br/>test:<ipsapp.models.Test object at 0x7f2b1070ac50>,connpool:<sqlalchemy.pool.QueuePool object at 0x7f2b1070ad10>

apache pid Test object QueuePool object
20016 0x7f2b1070ac50 0x7f2b1070ad10
20013 0x7f2b107c6c10 0x7f2b107c6cd0
20018 0x7f2b103c6c50 0x7f2b103c6d10
20016 0x7f2b1070ac50 0x7f2b1070ad10
20013 0x7f2b107c6c10 0x7f2b107c6cd0
20018 0x7f2b103c6c50 0x7f2b103c6d10
20016 0x7f2b1070ac50 0x7f2b1070ad10

我把分属于不同apache进程处理的请求用颜色标出了,在本例子中,7个请求,分配到了3个apache进程处理。可以看到,被同一个apache子进程处理的请求,是共用同一个test和test.connpool实例的,即他们共享数据库连接池。

所以,数据库连接池,对于web请求而言,是属于同一个apache子进程处理的请求共用一个数据库连接池。

以上这篇浅谈django url请求与数据库连接池的共享问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用Django连接Mysql数据库步骤

    链接mysql步骤 第一步:在终端下载pymysql文件–pip install pymysql 第二步:在gjango项目的__init__文件中添加代码 import pymysql pymysql .install_as_MySQLdb() 第三步:找到mysql的连接源,然后填信息,如果没有mysql驱动,需要下载MySQL驱动 mysql的配置:进入settings文件中找到DATABASES配置信息 DATABASES = { 'default': { 'ENGINE': 'djan

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

    Django的ORM是非常好用的,哪怕不是做Web项目也值得一用,所以网上也可以找到不少使用 Django 开发非Web项目的资料,因为除了ORM之个,命令行.配置文件等组件也非常好用. 最近用这种方式开发了一个非Web项目,而且是多线程的.有N个工作线程从DB中获取jobs,并把结果写回DB.简单来说就是这样. 项目运行一段时间后,发现数据库连接耗尽了,幸好内存大,然后一直往上调,最后连接数都上九千多一万了.耗尽连接数的时候,PostgreSQL 会出现类似这样的错误: FATAL: rema

  • django如何连接已存在数据的数据库

    你有没有遇到过这种情况? 数据库,各种表结构已经创建好了,甚至连数据都有了,此时,我要用Django管理这个数据库,ORM映射怎么办??? Django是最适合所谓的green-field开发,即从头开始一个新的项目 但是呢,Django也支持和以前遗留的数据库和应用相结合的. Django的数据库层从Python代码生成SQL schemas.但是对于遗留的数据库,你已经用于SQL schemas,这种情况下你需要为你已经存在的数据库表写模型(为了使用数据库的API),幸运的是,Django自

  • Django数据库连接丢失问题的解决方法

    问题 在Django中使用mysql偶尔会出现数据库连接丢失的情况,错误通常有如下两种 OperationalError: (2006, 'MySQL server has gone away') OperationalError: (2013, 'Lost connection to MySQL server during query') 查询mysql全局变量SHOW GLOBAL VARIABLES;可以看到wait_timeout,此变量表示连接空闲时间.如果客户端使用一个连接查询多次数

  • 浅谈django url请求与数据库连接池的共享问题

    但凡介绍数据库连接池的文章,都会说"数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正是针对这个问题提出来的.数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏.这项技术能明显提高对数据库操作的性能." 这句

  • 浅谈django中的认证与登录

    认证登录 django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1  authenticate(**credentials)    提供了用户认证,即验证用户名以及密码是否正确 一般需要username  password两个关键字参数 如果认证信息有效,会返回一个  User  对象.authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的.当我们试图登陆一个从数据库中直接取出来不经过authent

  • 浅谈Django自定义模板标签template_tags的用处

    自定义模板标签,过滤器.英文翻译是Customtemplatetagsandfilters.customfilter自定义过滤器今天不在我的记录范围之内,以后用到再看官方文档也不迟. **问题1:**customtemplatetags到底长啥样? customtemplatetags-github Manytemplatetagstakeanumberofarguments–stringsortemplatevariables–andreturnaresultafterdoingsomepro

  • 浅谈django不使用restframework自定义接口与使用的区别

    django可以使用restframework快速开发接口,返回前端所需要的json数据,但是有时候利用restframework开发的接口并不能满足所有的需求,这时候就需要自己手动开发接口,也就是将需要用到的某些对象转化为需要使用的json数据,今天记录一下django自己定义接口的一种方法与思路 假设我们定义三张数据表,分别是问卷,问题,选项.一张问卷包含不同的问题,一个问题可以设置不同的选项,自定义的接口可以实现查看所有或单个问卷的标题与id,可以查看所有或单个问题的所属问卷,问题标题,问

  • 浅谈Django前端后端值传递问题

    前端后端传值问题总结 前端传给后端 通过表单传值 1.通过表单get请求传值 在前端当通过get的方式传值时,表单中的标签的name值将会被当做action的地址的参数 此时,在后端可以通过get请求相应的name值拿到对应的value值 例子: html中: <form action="{% url 'backweb:select_art' %}" method="post"> {% csrf_token %} <section class=&q

  • 浅谈Django 页面缓存的cache_key是如何生成的

    页面缓存 e.g. @cache_page(time_out, key_prefix=key_prefix) def my_view(): ... 默认情况下,将使用配置中的default cache cache_page 装饰器是由缓存中间件 CacheMiddleware 转换而来的 CacheMiddleware 继承了 UpdateCacheMiddleware 和 FetchFromCacheMiddleware UpdateCacheMiddleware 继承自 Middleware

  • 浅谈Django REST Framework限速

    官方文档 settings.py配置 REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { 'anon': '100/day', 'user': '1000/day' } } AnonRateThrottle:用

  • 浅谈Django中的QueryDict元素为数组的坑

    一般在Django的视图函数中使用request.POST来获取请求体,request.POST是QueryDict类,通常作为dict来使用. 正常如下图 但是昨天在使用的时候遇到一个错误,提示从QueryDict里面pop出来的值类型为list. 一脸懵逼 在命令行敲代码,发现了这个坑, 如下图 可以看到,pop出来的值被放在的一个list里面.关键这个不同版本之间,行为还有所不同,就是因为在开发机器上一切正常,到了测试服务器就出问题才被发现的. 知道了问题,解决起来也简单,直接调用Quer

  • 浅谈django框架集成swagger以及自定义参数问题

    介绍 我们在实际的开发工作中需要将django框架与swagger进行集成,用于生成API文档.网上也有一些关于django集成swagger的例子,但由于每个项目使用的依赖版本不一样,因此可能有些例子并不适合我们.我也是在实际集成过程中遇到了一些问题,例如如何自定义参数等问题,最终成功集成,并将结果分享给大家. 开发版本 我开发使用的依赖版本,我所使用的都是截止发稿日期为止最新的版本: Django 2.2.7 django-rest-swagger 2.2.0 djangorestframe

  • 浅谈Java HttpURLConnection请求方式

    一)URL代理请求 ​ 该方式请求有两种代理方式. 方式一:使用该方式代理之后,之后的所有接口都会使用代理请求 // 对http开启全局代理 System.setProperty("http.proxyHost", "192.168.1.1"); System.setProperty("http.proxyPort", "80"); // 对https开启全局代理 System.setProperty("https.

随机推荐