一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - python自制簡易mysql連接池的實現示例

python自制簡易mysql連接池的實現示例

2022-02-24 00:33末日沙兔 Python

本文主要介紹了python自制簡易mysql連接池的實現示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

今天我們來說一點不一樣的, 使用python語言手擼mysql連接池.

連接池是什么?

連接池是創建和管理一個連接的緩沖池的技術,這些連接準備好被任何需要它們的線程使用。在并發量足夠時連接池一般比直接連接性能更優, 不僅提高了性能的同時還管理了寶貴的資源.

為什么需要連接池?

討論這個問題時, 我們需要先了解高并發導致服務器卡頓的原因出在哪里.

正常情況下, 每當一位用戶使用各類終端連接到服務器的時候, 服務器都需要開辟一片內存為其服務, 每當一個請求從前端傳入都需在mysql之間創建一條連接. 然而過多的連接會導致服務器卡頓內存占用過高, 這時候就需要連接池對所有連接狀態進行管理, 合理分配&回收資源.

簡單說就是使用連接池技術可用減少服務器壓力.

連接池的原理是什么?

連接池主要需要兩個參數,默認連接數、最大連接數

  • 當服務啟動時, 首先創建默認連接數的空閑連接放入池中.
  • 當用戶需要連接時, 首先查看池中是否有空閑連接.
    • 如果有: 由連接池分配從池中取出一個空閑連接交付用戶使用.
    • 如果沒有: 查看當前存活的所有連接總數是否大于最大連接.
      • 如果小于: 創建新連接交付用戶使用.
      • 如果等于: 線程阻塞, 等待有空閑連接再交予用戶.
  • 當用戶用完連接后, 查看當前存活連接數是否大于默認值.
  • 如果小于等于: 將此條連接重新放入空閑池中, 等待下一次使用.
  • 如果大于: 將此條連接釋放銷毀, 不放入池中.

使用python語言自制簡易mysql連接池

這里, 我們需要 ThemisPool.py 連接池本身, db.cnf 配置文件, 其目錄路徑如下:

?
1
2
3
4
5
6
7
8
9
# 推薦目錄格式, ThemisPool.py & db.cnf 只需要在同級目錄下即可
[your python project]
    |
    |
    |-- util
         |
         |-- db.cnf
         |
         |-- ThemisPool.py

ThemisPool.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# 導入依賴
# mysql連接基本庫
import pymysql
 
# 讀取配置文件所需要的庫
import configparser
import 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 配置文件

?
1
2
3
4
5
6
7
[mysql]
host = localhost
user = root
password = 12345678
database = practice
initsize = 3
maxsize = 6

所有配置屬性

 

參數 說明 類型 默認值
host 主機地址 str localhost
port 端口號 int 3306
user mysql登錄用戶名 str root
password mysql登錄密碼 str -
database 訪問庫名 str -
initsize 初始化連接數 int 3
maxsize 最大連接數 int 6

 

開始使用

?
1
2
3
4
5
6
7
8
9
10
11
12
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]

?
1
2
3
4
5
6
7
8
9
# myDB.cnf
 
[mysqlConfig]
host = localhost
user = root
password = 12345678
database = practice
initsize = 3
maxsize = 6
?
1
2
3
4
# 使用時
...
db = ThemisPool(fileName='myDB.cnf', configName='mysqlConfig')
...

命名思路

Themis(忒彌斯) 取名來自于古希臘神話中秩序女神的名字, 就如同連接池的作用一樣, 管理所有用戶的連接, 減少不必要的損耗。

GitHub地址

ThemisPool連接池

以上就是本次的全部內容, 下版本將會解決 python 不能對 datetime 類型的數據進行 json格式化 的問題, 并將它集成進來

到此這篇關于python自制簡易mysql連接池的實現示例的文章就介紹到這了,更多相關python mysql連接池內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/7022684526891499528

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 女女宿舍互慰h文小说 | 能看的毛片网站 | 四虎在线网址 | 欧美穿高跟鞋做爰 | 亚洲国产美女精品久久 | 插插好爽爽爽 | 好男人资源免费播放 | 五花大绑esebdsm国产 | 亚洲色图第四页 | 欧美日韩一区二区三区在线播放 | 免费看男女做好爽好硬视频 | 国产午夜精品福利 | 亚洲国产在线99视频 | 亚洲精品123区在线观看 | 国产精品女同久久免费观看 | 欧美破处摘花 | 日本加勒比一区 | 99国产国人青青视频在线观看 | 欧美 变态 另类 人妖班 | 操弄哥哥的108种姿势 | 粉嫩尤物在线456 | 嫩草影院国产 | 五月一区二区久久综合天堂 | 国产精品13p | 青草香蕉精品视频在线观看 | 国产成人高清亚洲一区91 | 国产亚洲成归v人片在线观看 | 天若有情1992国语版完整版 | 四虎影视色费永久在线观看 | 四虎最新永久免费视频 | 五月桃花网婷婷亚洲综合 | tk白丝丨vk | 欧美1区| nhdta系列媚药系列 | 视频大全在线观看免费 | 欧美精选视频 | 女人c交zzzooo在线观看 | 奇米影视先锋 | 亚洲欧美一区二区久久 | 国产成人精品一区二三区 | 亚洲va精品中文字幕 |