一、自己实现的一个简单的连接池
简单概括:其他还好,稳定性有待验证
import pymysql
class SqlPool:
_singleton = None
_conn = {} # 连接池字典
_js = {} # 连接数量字典
_minSize = 3 # 空闲时的连接数,需要最大连接达到
_maxSize = 10 # 最大连接数
def __new__(cls, *args, **kwargs):
if not cls._singleton:
cls._singleton = super(SqlPool, cls).__new__(cls)
return cls._singleton
def __init__(self, name):
# name:数据库名称
self.re_conn(name)
def re_conn(self, name, res=False):
_conn = self._conn
_js = self._js
self.name = name
if name not in _conn or res:
_conn[name] = []
_js[name] = 0
if not _conn[name] and _js[name] <= self._maxSize:
conn = pymysql.connect(db=name, user=config['U']['us'], passwd=config['U']['ps'],
host=config['U']['hs'],
charset='utf8')
_conn[name].append(conn)
_js[name] += 1
def get_conn(self, name,closed=False):
''' 获取连接 '''
_conn = self._conn
if closed:
self.re_conn(name, res=True)
if name not in _conn or not _conn[name]:
self.re_conn(name)
conn = _conn[name].pop()
return conn
def set_conn(self, name, conn):
''' 每使用完连接后,需回收连接 '''
_conn = self._conn[name]
l_c = len(_conn)
if l_c < self._minSize:
_conn.append(conn)
else:
_js = self._js[name]
_js = _js-1 if _js>0 else l_c
conn.close()
def test():
sp = SqlPool('db_name')
conn = sp.get_conn('db_name')
cur = conn.cursor()
cur.execute('select * from tables')
sp.set_conn('db_name',conn)
return cur.fetchall()
二、使用 python 模块 DBUtils 来实现
1,PersistentDB
# 简单概括:性能稍好,稳定性稍有不足
from DBUtils.PersistentDB import PersistentDB
import pymysql
Pool = PersistentDB(
creator = pymysql, # 使用连接数据库的模块
maxusage = None, # 一个连接最多被使用的次数,None为无限制
setsession = [], # 开始会话前执行的命令
ping = 0, # ping MySQL服务端,检查服务是否可用
closeable = False, # conn.close() 被忽略,供下次使用,直到线程关闭,自动关闭连接。而等于True时,conn.close()真的被关闭
threadlocal = None, # 本线程独享值的对象,用于保存连接对象
host = 'localhost',
port = 3306,
user = 'root',
passwd = '123456',
db = 'test',
charset = 'utf8'
)
2,PooledDB
# 简单概括:稳定性稍好,性能稍有不足
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB,SharedDBConnection
POOL = PooledDB(
creator = pymysql, #使用链接数据库的模块
maxconnections = 6, #连接池允许的最大连接数,0和None表示没有限制
mincached = 2, #初始化时,连接池至少创建的空闲的连接,0表示不创建
maxcached = 5, #连接池空闲的最多连接数,0和None表示没有限制
maxshared = 3, #连接池中最多共享的连接数量,0和None表示全部共享,ps:其实并没有什么用,因为pymsql和MySQLDB等模块中的threadsafety都为1,所有值无论设置多少,_maxcahed永远为0,所以永远是所有链接共享
blocking = True, #链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
setsession = [],#开始会话前执行的命令列表
ping = 0,#ping Mysql 服务端,检查服务是否可用
host = '127.0.0.1',
port = 3306,
user = 'root',
passwd = '123456',
db = 'test',
charset = 'utf8'
)
def func():
#检测当前正在运行的连接数是否小于最大的连接数,如果不小于则等待连接或者抛出raise TooManyConnections异常
#否则优先去初始化时创建的连接中获取连接SteadyDBConnection
#然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回
#如果最开始创建的连接没有链接,则去创建SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回
#一旦关闭链接后,连接就返回到连接池让后续线程继续使用
conn = POOL.connection()
cursor = conn.cursor()
cursor.execute('select * from table')
result = cursor.fetchall()
print(result)
conn.close()
func()