使用到的模塊: DBUtils
實現:
-
使用 DBUtils 中的 PooledDB 類來實現.
-
自己寫一個類, 繼承 PooledDB 類, 這樣就能使用到 PooledDB 中的其它常用的方法.
-
使用單例模式, 確保整個應用服務中只有一個連接池對象.
-
使用: 可以定義全局變量初始化連接池對象, 在別的地方獲取mysql連接使用.
連接池 demo:
# coding: utf-8 import pymysql import functools from seemmo.common.time_func import now_time, today from conf.config import DB_HOST, DB_PORT, DB_USER, DB_NAME, DB_CHARSET from pymysql.cursors import DictCursor from DBUtils.PooledDB import PooledDB # 獲取加密的mysql密碼 from seemmo.common.utils import get_pwd DB_PASSWD = get_pwd("mysql_pwd") class MysqlPool(PooledDB): __instance = None __pool = None def __new__(cls, *args, **kwargs): if not cls.__instance: # cls.__instance = object.__new__(cls) cls.__instance = super().__new__(cls) return cls.__instance def __init__(self): """創建鏈接池""" PooledDB.__init__(self, pymysql, maxconnections=50, mincached=0, maxcached=0, maxshared=0, blocking=True, host=DB_HOST, port=DB_PORT,user=DB_USER, password=DB_PASSWD, database=DB_NAME, charset=DB_CHARSET, cursorclass=DictCursor) def conn(self): _conn = self.connection() return _conn
使用 (裝飾器) :
# 創建連接池對象 mysql_pool = MysqlPool() # mysql 閉包環境 def db_wrap(method): @functools.wraps(method) def _wrapper(*args, **kwargs): conn = mysql_pool.conn() cursor = conn.cursor() try: conn.begin() retval = method(cursor, *args, **kwargs) conn.commit() except Exception as e: conn.rollback() raise e finally: cursor.close() conn.close() return retval return _wrapper @db_wrap def create_table(cursor, sql): ret = cursor.execute(sql) return ret @db_wrap def query_by_index(cursor, table_name, start_index, next_index): """ 根據 index 范圍查詢違法記錄 :param cursor: 數據庫操作游標 :param table_name: 需要操作的表名稱 :param start_index: 開始 index :param next_index: 截止 index :return: 查詢結果 """ sql = """select * from {} where id > {} and id <= {}""".format(table_name, start_index, next_index) cursor.execute(sql) res = cursor.fetchall() return res
PooledDB的參數:
-
mincached,最少的空閑連接數,如果空閑連接數小於這個數,pool會創建一個新的連接
-
maxcached,最大的空閑連接數,如果空閑連接數大於這個數,pool會關閉空閑連接
-
maxconnections,最大的連接數,
-
blocking,當連接數達到最大的連接數時,在請求連接的時候,如果這個值是True,請求連接的程序會一直等待,直到當前連接數小於最大連接數,如果這個值是False,會報錯,
-
maxshared 當連接數達到這個數,新請求的連接會分享已經分配出去的連接
在uwsgi中,每個http請求都會分發給一個進程,連接池中配置的連接數都是一個進程為單位的(即上面的最大連接數,都是在一個進程中的連接數),而如果業務中,一個http請求中需要的sql連接數不是很多的話(其實大多數都只需要創建一個連接),配置的連接數都不需要太大。
連接池對性能的提升表現在:1.在程序創建連接的時候,可以從一個空閑的連接中獲取,不需要重新初始化連接,提升獲取連接的速度2.關閉連接的時候,把連接放回連接池,而不是真正的關閉,所以可以減少頻繁地打開和關閉連接
DBUtils下載地址:https://pypi.python.org/pypi/DBUtils/
ending ~