python自制简易mysql连接池的实现方法是什么
这篇文章主要讲解了“python自制简易mysql连接池的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python自制简易mysql连接池的实现方法是什么”吧!
连接池是什么?
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。在并发量足够时连接池一般比直接连接性能更优, 不仅提高了性能的同时还管理了宝贵的资源.
为什么需要连接池?
讨论这个问题时, 我们需要先了解高并发导致服务器卡顿的原因出在哪里.
正常情况下, 每当一位用户使用各类终端连接到服务器的时候, 服务器都需要开辟一片内存为其服务, 每当一个请求从前端传入都需在mysql之间创建一条连接. 然而过多的连接会导致服务器卡顿内存占用过高, 这时候就需要连接池对所有连接状态进行管理, 合理分配&回收资源.
简单说就是使用连接池技术可用减少服务器压力.
连接池的原理是什么?
连接池主要需要两个参数,默认连接数、最大连接数
当服务启动时, 首先创建默认连接数的空闲连接放入池中.
当用户需要连接时, 首先查看池中是否有空闲连接.
如果小于: 创建新连接交付用户使用.
如果等于: 线程阻塞, 等待有空闲连接再交予用户.
如果有: 由连接池分配从池中取出一个空闲连接交付用户使用.
如果没有: 查看当前存活的所有连接总数是否大于最大连接.
当用户用完连接后, 查看当前存活连接数是否大于默认值.
如果小于等于: 将此条连接重新放入空闲池中, 等待下一次使用.
如果大于: 将此条连接释放销毁, 不放入池中.
使用python语言自制简易mysql连接池
这里, 我们需要 ThemisPool.py 连接池本身, db.cnf 配置文件, 其目录路径如下:
# 推荐目录格式, ThemisPool.py & db.cnf 只需要在同级目录下即可[your python project] | | |-- util | |-- db.cnf | |-- ThemisPool.py
ThemisPool.py
# 导入依赖# mysql连接基本库import pymysql# 读取配置文件所需要的库import configparserimport os# 线程管理所需要的库import threading# 创建配置类用户读取配置文件class Config(object): def __init__(self, configFileName='db.cnf'): file = os.path.join(os.path.dirname(__file__), configFileName) self.config = configparser.ConfigParser() self.config.read(file) def getSections(self): return self.config.sections() def getOptions(self, section): return self.config.options(section) def getContent(self, section): result = {} for option in self.getOptions(section): value = self.config.get(section, option) result[option] = int(value) if value.isdigit() else value return result # 将连接所需要的参数封装在对象中 # 依次为: 数据库密码、需要连接的库名、主机地址[默认 localhost]、端口号[默认 3306]、初始化连接数[默认 3]、最大连接数[默认 6]class parameter(object): def __init__(self, password, database, host="localhost",port="3306" user="root", initsize=3, maxsize=6): self.host = str(host) self.port = int(port) self.user = str(user) self.password = str(password) self.database = str(database) self.maxsize = int(maxsize) self.initsize = int(initsize)# 连接池class ThemisPool(parameter): def __init__(self, fileName='db.cnf', configName='mysql'): # 加载配置文件, 配置文件名默认为 'db.cnf', 配置标签默认为 'mysql' self.config = Config(fileName).getContent(configName) super(ThemisPool, self).__init__(**self.config) # 创建队列作为 池 self.pool = queue.Queue(maxsize=self.maxsize) self.idleSize = self.initsize # 创建线程锁 self._lock = threading.Lock() # 初始化连接池 for i in range(self.initsize): # 创建 初始化连接数 数量的连接放入池中 self.pool.put(self.createConn()) # 启动日志 print('\033[1;32m ThemisPool connect database {database}, login is {user} \033[0m'.format(database=self.database, user=self.user)) # 生产连接 def createConn(self): # 使用mysql基本类 # pymysql.connect 参数这里不做解释,具体请查阅官网 https://pypi.org/project/PyMySQL/ return pymysql.connect(host=self.host, port=self.port, user=self.user, password=self.password, database=self.database, charset='utf8') # 获取连接 def getConn(self): self._lock.acquire() try: # 如果池中连接够直接获取 if not self.pool.empty(): self.idleSize -= 1 else: # 否则重新添加新连接 if self.idleSize < self.maxsize: self.idleSize += 1 self.pool.put(self.createConn()) finally: self._lock.release() return self.pool.get() # 释放连接 def releaseCon(self, conn=None): try: self._lock.acquire() # 如果池中大于初始值就将多余关闭,否则重新放入池中 if self.pool.qsize() < self.initsize: self.pool.put(conn) self.idleSize += 1 else: try: # 取出多余连接并关闭 surplus = self.pool.get() surplus.close() del surplus self.idleSize -= 1 except pymysql.ProgrammingError as e: raise e finally: self._lock.release() # 拉取数据(查询) # 可用语句类型 (select) def fetchone(self, sql): themis = None cursor = None try: themis = self.getConn() cursor = themis.cursor() cursor.execute(sql) return cursor.fetchall() except pymysql.ProgrammingError as e: raise e except pymysql.OperationalError as e: raise e except pymysql.Error as e: raise e finally: cursor.close() self.releaseCon(themis) # 更新 # 可用语句类型 (insert, update, delete) def update(self, sql): themis = None cursor = None try: themis = self.getConn() cursor = themis.cursor() cursor.execute(sql) return cursor.lastrowid except pymysql.ProgrammingError as e: raise e except pymysql.OperationalError as e: raise e except pymysql.Error as e: raise e finally: themis.commit() cursor.close() self.releaseCon(themis) # 释放连接池本身 def __del__(self): try: while True: conn = self.pool.get_nowait() if conn: conn.close() except queue.Empty: pass
db.cnf 配置文件
[mysql]host = localhostuser = rootpassword = 12345678database = practiceinitsize = 3maxsize = 6
所有配置属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
host | 主机地址 | str | localhost |
port | 端口号 | int | 3306 |
user | mysql登录用户名 | str | root |
password | mysql登录密码 | str | - |
database | 访问库名 | str | - |
initsize | 初始化连接数 | int | 3 |
maxsize | 最大连接数 | int | 6 |
开始使用
from util.ThemisPool import ThemisPool# 初始化ThemisPool连接池 (Initialize the ThemisPool connection pool)db = ThemisPool()# 查询拉取数据,函数会直接返回数据 (Query pull data.It returns data directly)selectSql = "select * from user;"data = db.fetchone(selectSql)# 增、删、改语句, 如果有使用mysql自增长插入的值函数会返回自增长的数据 (insert,upate delete and alter. If there is a value function inserted using mysql self-growth, it will return self-growth data)insertSql = "insert into user values(null,'user001','123456')"id = db.update(selectSql)
自定义配置文件名 & 配置标签
配置文件名默认为 db.cnf, 配置标签默认为 [mysql]
例如自定义配置文件名为 myDB.cnf, 配置标签为 [mysqlConfig]
# myDB.cnf[mysqlConfig]host = localhostuser = rootpassword = 12345678database = practiceinitsize = 3maxsize = 6
# 使用时...db = ThemisPool(fileName='myDB.cnf', configName='mysqlConfig')...
命名思路
Themis(忒弥斯) 取名来自于古希腊神话中秩序女神的名字, 就如同连接池的作用一样, 管理所有用户的连接, 减少不必要的损耗。
GitHub地址
ThemisPool连接池
感谢各位的阅读,以上就是“python自制简易mysql连接池的实现方法是什么”的内容了,经过本文的学习后,相信大家对python自制简易mysql连接池的实现方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341