隨著全網掃描項目的開發,越來越細致的問題暴露出來,從能用到用的好,還有很長的路要走。

這個問題前段時間就發現了,程序一般跑個一天會越來越慢,直到某個時候程序徹底崩了,而且最后的報錯也一般是mysql的報錯:

pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query ([Errno 104] Connection reset by peer)')

我突然意識到,并不是程序有問題,否則也不會跑這么長時間,而是與數據的連接不穩定導致,而之所以與數據庫連接不穩定是因為程序有大量的web請求與mysql插入與查詢請求。

之所以會越來越慢是因為一開始所有線程都還是存活狀態,但是當某個線程遇到mysql連接出了問題的時候 該線程會立刻死掉,mysql連接問題會是間歇性的,所以線程都開始慢慢死掉,當最后一個線程死掉的時候主線程也就結束了。

前期的解決方案

最開始我用的是簡單的方案,所有線程都用的是一個mysql連接,從始至終只有這一個連接,這個連接斷掉,程序也就over。

后來我開始在每次執行一個sql的時候都單獨建立一個mysql連接,執行完就close掉,很明顯這樣的問題在于,頻繁連接,斷開mysql,這樣是相當消耗系統資源的,而且增加了mysql連接失敗的幾率,所以萬一哪個線程沒有連接成功 這個線程也over了。

最終解決方案:DBUtils

最終的解決方案還是用了數據庫連接池,而且個人覺得這是個相當完美的方案。

在介紹模塊的使用方法之前還是先說下原理:

1.在程序創建連接的時候,可以從一個空閑的連接中獲取,不需要重新初始化連接,提升獲取連接的速度
2.關閉連接的時候,把連接放回連接池,而不是真正的關閉,所以可以減少頻繁地打開和關閉連接

DBUtils模塊demo

下載地址:https://pypi.python.org/pypi/DBUtils/

直接上一個直觀的demo,算是給自己的一個備忘

import pymysql
from DBUtils.PooledDB import PooledDB
pool = PooledDB(pymysql,50,host='localhost',user='root',passwd='pwd',db='myDB',port=3306 charset="utf8") #5為連接池里的最少連接數
conn = pool.connection() #以后每次需要數據庫連接就是用connection()函數獲取連接就好了
cur=conn.cursor()
SQL="select * from table1"
r=cur.execute(SQL)
r=cur.fetchall()
cur.close()
conn.close()

 

您的支持將鼓勵我們繼續創作!

[微信] 掃描二維碼打賞

[支付寶] 掃描二維碼打賞