淺談django url請求與數(shù)據(jù)庫連接池的共享問題
但凡介紹數(shù)據(jù)庫連接池的文章,都會說“數(shù)據(jù)庫連接是一種關(guān)鍵的有限的昂貴的資源,這一點在多用戶的網(wǎng)頁應(yīng)用程序中體現(xiàn)得尤為突出。對數(shù)據(jù)庫連接的管理能顯著影響到整個應(yīng)用程序的伸縮性和健壯性,影響到程序的性能指標(biāo)。數(shù)據(jù)庫連接池正是針對這個問題提出來的。數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接來避免因為沒有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏。這項技術(shù)能明顯提高對數(shù)據(jù)庫操作的性能。”
這句話雖然說得很好,但也很讓人疑惑。比如,多個請求是怎樣共用數(shù)據(jù)庫連接池???
其實,數(shù)據(jù)庫連接池主要是利用了程序,靜態(tài)變量與靜態(tài)方法的概念實現(xiàn)的。靜態(tài)變量和靜態(tài)方法,是程序運行時,就被加載到內(nèi)存中的。該進(jìn)程中所有對于它的訪問,都是對“唯一”的它的訪問。所以,才能有數(shù)據(jù)庫連接池被共享的概念。

可以看到,靜態(tài)變量a以及靜態(tài)方法add,即使類A從未被實例化過,它們也都會被加載到內(nèi)存中。
另外,在python的此次運行(一個進(jìn)程)中,多次對a的操作,都是對為一個的這個a變量的操作,所以它的值是在被操作后累加的。
這個在我上面簡單的例子中很好理解。那么如何理解Web應(yīng)用程序(如django程序)在接到url請求時的場景呢?在多個請求時,他們是如何可以共享數(shù)據(jù)庫連接池的?
我寫了一個簡單的例子:
Test model,使用了單例模式,它的功能是調(diào)用sqlalchemy.pool中的數(shù)據(jù)庫連接池。

而views.py的index方法,則是調(diào)用Test的getinstance方法獲得它的實例,同時用它的數(shù)據(jù)庫連接池。

為了看得清楚,我在這個方法中增加打印了當(dāng)前所屬進(jìn)程的pid,test和test.connpool信息。
首先要說明一點,apache在windows和linux中的運行方式不盡相同(windows是兩個httpd進(jìn)程,一個父進(jìn)程,一個子進(jìn)程,子進(jìn)程里面多個線程處理請求)。在linux中,默認(rèn)用prefork的方式運行。即一個父進(jìn)程,多個子進(jìn)程,這多個子進(jìn)程負(fù)責(zé)處理web請求。
如下圖所示:

然后我們嘗試多次url請求(適當(dāng)變化url,避免緩存);并記錄結(jié)果:
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進(jìn)程處理的請求用顏色標(biāo)出了,在本例子中,7個請求,分配到了3個apache進(jìn)程處理??梢钥吹剑煌粋€apache子進(jìn)程處理的請求,是共用同一個test和test.connpool實例的,即他們共享數(shù)據(jù)庫連接池。
所以,數(shù)據(jù)庫連接池,對于web請求而言,是屬于同一個apache子進(jìn)程處理的請求共用一個數(shù)據(jù)庫連接池。
以上這篇淺談django url請求與數(shù)據(jù)庫連接池的共享問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python函數(shù)之zip函數(shù)的介紹與實際應(yīng)用
zip() 函數(shù)用于將可迭代的對象作為參數(shù),將對象中對應(yīng)的元素打包成一個個元組,然后返回由這些元組組成的對象(python2 返回的是這些元組組成的列表 ),下面這篇文章主要給大家介紹了關(guān)于Python函數(shù)之zip函數(shù)實際應(yīng)用的相關(guān)資料,需要的朋友可以參考下2022-03-03
Python實現(xiàn)讀取csv文件并進(jìn)行排序
這篇文章主要為大家詳細(xì)介紹了一個python簡單案例并進(jìn)行代碼展示,本文的案例是利用pandas庫實現(xiàn)讀取csv文件并按照列的從小到大進(jìn)行排序,需要的可以參考一下2023-02-02
使用Python編寫一個粘貼python源代碼就能運行的工具
以下是一個使用wxPython模塊創(chuàng)建帶有Memo(文本輸入框)和保存按鈕的GUI程序示例,點擊保存按鈕后將Memo內(nèi)容保存到指定路徑下的文件,并提供運行按鈕以執(zhí)行指定的Python腳本,需要的朋友可以參考下2025-04-04
Python?matplotlib.pyplot.hist()繪制直方圖的方法實例
直方圖(Histogram)又稱質(zhì)量分布圖,是一種統(tǒng)計報告圖,由一系列高度不等的縱向條紋或線段表示數(shù)據(jù)分布的情況,一般用橫軸表示數(shù)據(jù)類型,縱軸表示分布情況,下面這篇文章主要給大家介紹了關(guān)于Python?matplotlib.pyplot.hist()繪制直方圖的相關(guān)資料,需要的朋友可以參考下2022-06-06

