1.Flask路由 |
數據庫鏈接池負責分配、管理和釋放數據庫鏈接,它容許應用程序重複使用一個現有的數據庫鏈接,而不是再從新創建一個;釋放空閒時間超過最大空閒時間的數據庫鏈接來避免由於沒有釋放數據庫鏈接而引發的數據庫鏈接資源。mysql
用戶每次請求都須要向數據庫得到連接,而數據庫建立鏈接一般須要消耗相對較大的資源,建立時間也較長。假設網站一天10萬訪問量,數據庫服務器就須要建立10萬次鏈接,極大的浪費數據庫的資源,而且極易形成數據庫服務器內存溢出拓機。以下圖所示:sql
數據庫鏈接是一種關鍵的有限的昂貴的資源, 這一點在多用戶的網頁應用程序中體現的尤其突出。對數據庫鏈接的管理能顯著影響到整個應用程序的伸縮性和健壯性,影響到程序的性能指標,數據庫鏈接池正式針對這個問題提出來的。數據庫鏈接池負責分配,管理和釋放數據庫鏈接,它容許應用程序重複使用一個現有的數據庫鏈接,而不是從新創建一個。以下圖所示:數據庫
數據庫鏈接池在初始化時將建立必定數量的數據庫鏈接放到鏈接池中,這些數據庫鏈接的數量是由最小數據庫鏈接數來設定的,不管這些數據庫鏈接是否被使用,鏈接池都將一直保證至少擁有這麼多的鏈接數量。鏈接池的最大數據庫連接數量限定了這個鏈接池能佔有的最大鏈接數,當應用程序向鏈接池請求的鏈接數超過最大鏈接數量時,這些請求將被加入到等待隊列中。json
數據庫鏈接池的最小鏈接數和最大鏈接數的設置要考慮到如下幾個因素:瀏覽器
DBUtils是一套Python數據庫鏈接池包,並容許對非線程安全的數據庫接口進行線程安全包裝。DBUtils來自Webware for Python 。安全
DBUtils提供兩種外部接口:服務器
安裝DButils,它依賴於pymysqlsession
pip install pymysql
pip install DBUtils
首先保證你有一個MySQL服務器,而且已經啓動了!已經有一個數據庫以及表數據app
以前咱們要操做MySQL,使用pymysql函數
import pymysql conn = pymysql.connect(host='localhost', port=3306, user='root', password='', db='student', charset='utf8') cur = conn.cursor(pymysql.cursors.DictCursor) # 插入一條數據 sql = "insert into stu(name,age) value ('%s','%s')" % ('小甜甜', 22) cur.execute(sql) conn.commit() cur.close() conn.close()
能夠發現,每次操做數據庫,都須要鏈接數據庫。須要消耗連接時間!效率很是低!
新建文件utils.py,內容以下:
確保主機ip 127.0.0.1,數據庫book,用戶名root,密碼爲空,可以鏈接MySQL
import pymysql from DBUtils.PooledDB import PooledDB POOL = PooledDB( creator=pymysql, # 使用鏈接數據庫的模塊 maxconnections=6, # 鏈接池容許的最大鏈接數,0和None表示不限制鏈接數 mincached=2, # 初始化時,連接池中至少建立的空閒鏈接,0表示不建立 maxcached=5, # 鏈接池中最多閒置的鏈接,0和None不限制 maxshared=1, # 連接池中最多共享的鏈接數量,0和None表示所有共享。PS:無用,由於pymysql和MySQLdb等模塊的threadsafety都 # 爲1,全部值不管設置爲多少,_maxcached永遠爲0,因此永遠是全部鏈接都共享。 blocaking=True, # 鏈接池中若是沒有可用鏈接後,是否阻塞等待,True,等待;False,不等待而後報錯 maxusage=None, # 一個鏈接最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表,如["set datestyle to ...", "set time zone ..."] ping=0, # ping MySQL服務器,檢查是否服務可用。 # 如:0 = None = never, # 1 = default = whenever it is requested, # 2 = when a cursor is created, # 4 = when a query is executed, # 7 = always host='127.0.0.1', port=3306, user='root', password='', database='book', charset='utf8' )
maxconnections 最大鏈接數,不建議寫0。可能會拖死服務器!
ping = 0 表示關閉服務檢測。它會耗費服務器性能
注意:如下這些參數是必需要有的
creator=pymysql, host='127.0.0.1', port=3306, user='root', password='', database='book', charset='utf8' |
新建文件poolconn.py,確保book數據庫已經建立了表student,並錄入了數據
from utils import POOL import pymysql def func(): # 檢測當前正在運行鏈接數的是否小魚最大鏈接數,若是不小於則:等待或包raise TooManyConnections異常 # 不然,則優先去初始化時建立的鏈接中獲取鏈接SteadyDBConnection。 # 而後將SteadyDBConnection對象封裝到PooledDedicatedDBConnection中並返回。 # 若是最開始建立的鏈接沒有鏈接,組曲建立一個SteadyDBConnection對象,再封裝到PooledDedicatedDBConnection中並返回。 # 一旦關閉鏈接後,鏈接就返回到鏈接池讓後續線程繼續使用。 conn = POOL.connection() # 從鏈接池POOL中拿出一個已經建立好的鏈接,一次只能拿一個 cursor = conn.curson(pymysql.cursors.DictCursor) cursor.execute('select * from student') result = list(cursor.fetchall()) # 使用list效率是很低的,這裏僅作測試 print(result) cursor.close() conn.close() func()
執行輸出:
[{'age': 24, 'name': '韓雪', 'id': 1, 'gender': '女'}, {'age': 23, 'name': '舒暢', 'id': 2, 'gender': '女'}, {'age': 25, 'name': '唐嫣', 'id': 3, 'gender': '女'}] |
爲了方便操做MySQL,須要將增刪改查操做,封裝成一個類,方便程序調用!
import pymysql from DBUtils.PooledDB import PooledDB import DB_config as Config """功能:PT數據庫鏈接池""" class PTConnectionPool(object): __pool = None def __enter__(self): self.conn = self.__getConn() self.cursor = self.conn.cursor() print('PT數據庫建立conn和cursor') return self def __getConn(self): if self.__pool is None: self.__pool = PooledDB(creator=pymysql, mincached=Config.DB_MIN_CACHED, maxcached=Config.DB_MAX_CACHED, maxshared=Config.DB_MAX_SHARED, maxconnections=Config.DB_MAX_CONNECYIONS, blocking=Config.DB_BLOCKING, maxusage=Config.DB_MAX_USAGE, setsession=Config.DB_SET_SESSION, host=Config.DB_TEST_HOST, port=Config.DB_TEST_POST, user=Config.DB_TEST_USER, passwd=Config.DB_TEST_PASSWORD, db=Config.DB_TEST_DBNAME, use_unicode=Config.DB_USE_UNICODE, charset=Config.DB_CHARSET) return self.__pool.connection() """summary:釋放鏈接池資源""" def __exit__(self, type, value, trace): self.cursor.close() self.conn.close() print('PT鏈接池釋放conn和cursor') # 重鏈接池中取出一個鏈接 def getconn(self): conn = self.__getConn() # 設置返回數據爲字典 cursor = conn.cursor(pymysql.cursors.DictCursor) return cursor, conn def getPTConnection(): return PTConnectionPool()
配置文件:DB_config.py
# TEST數據庫信息 DB_TEST_HOST = '192.168.37.131' DB_TEST_POST = '3306' DB_TEST_DBNAME = 'book' DB_TEST_USER = 'root' DB_TEST_PASSWORD = '123456' # 數據庫鏈接編碼 DB_CHARSET = 'utf8' # mincached:啓動時開啓的閒置鏈接數量(缺省值0開始時不建立鏈接) DB_MIN_CACHED = 10 # maxcached:鏈接池中容許的閒置的最多鏈接數量(缺省值0表明不閒置鏈接池大小) DB_MAX_CACHED = 10 # maxshared:共享鏈接數容許的最大數量(缺省值0表明全部鏈接都是專用的)若是達到了最大數量,被請求爲貢獻的鏈接將會被共享使用 DB_MAX_SHARED = 20 # maxconnecyions:建立鏈接池的最大數量(缺省值0表明不限制) DB_MAX_CONNECYIONS = 100 # blocking:設置在鏈接池達到最大數量時的行爲(缺省值0或False表明返回一個錯誤<toMany...>其餘表明阻塞直到鏈接數減小,鏈接被分配) DB_BLOCKING = True # maxusage:單個鏈接的最大容許複用次數(缺省值0或False表明不限制的複用),當達到最大數時,鏈接會自動從新鏈接(關閉和從新打開) DB_MAX_USAGE = 0 # setsession:一個可選的SQL命令列表用於準備每一個會話,如["set datestyle to german", ...] DB_SET_SESSION = None # 是否使用unicode編碼 DB_USE_UNICODE = True
封裝的mysqlhelp.py