多線程爬蟲中實現線程安全的MySQL連接池

多線程爬蟲中實現線程安全的MySQL連接池

在日常開發中,數據庫操作頻繁建立/關閉連接會帶來性能損耗,尤其在多線程場景中更容易出現連接復用、阻塞等問題。因此,本文介紹如何使用 Python 封裝一個 線程安全的 MySQL 連接池,并通過 threading 模擬多線程高并發操作數據庫。


一、項目背景

  • 目標: 封裝一個通用的、可復用的、線程安全的 MySQL 連接池類
  • 實現: 使用 DBUtilsPooledDB 實現底層連接池邏輯,支持最大連接數、最小緩存連接數等參數
  • 特點:
    • 多線程安全
    • 自動釋放連接
    • 封裝常用的 CRUD 操作
    • 內置異常處理與日志輸出

二、依賴準備

pip install pymysql DBUtils

三、連接池封裝代碼(ConnectionPool)

# CoreUtils/Sql.py
import pymysql
import logging
import traceback
from DBUtils.PooledDB import PooledDBclass ConnectionPool:"""多線程同步連接池"""def __init__(self, host, database, user=None, password=None,port=3306, charset="utf8mb4", max_connections=10,min_cached=2, max_cached=5, blocking=True):"""初始化連接池"""self._pool = PooledDB(creator=pymysql,maxconnections=max_connections,mincached=min_cached,maxcached=max_cached,blocking=blocking,host=host,port=port,user=user,password=password,database=database,charset=charset,use_unicode=True,cursorclass=pymysql.cursors.DictCursor,autocommit=True)def _get_conn(self):return self._pool.connection()def query(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.fetchall()finally:cursor.close()conn.close()def get(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.fetchone()finally:cursor.close()conn.close()def execute(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:return cursor.execute(sql, params)except Exception as e:traceback.print_exc()logging.error(f"SQL執行錯誤: {e}\nSQL: {sql}\nParams: {params}")raisefinally:cursor.close()conn.close()def insert(self, sql, params=None):conn = self._get_conn()cursor = conn.cursor()try:cursor.execute(sql, params)return cursor.lastrowidexcept Exception as e:logging.error(f"插入出錯: {e}\nSQL: {sql}\nParams: {params}")raisefinally:cursor.close()conn.close()def table_has(self, table_name, field, value):sql = f"SELECT {field} FROM {table_name} WHERE {field}=%s LIMIT 1"return self.get(sql, value)def table_insert(self, table_name, item: dict):fields = list(item.keys())values = list(item.values())placeholders = ','.join(['%s'] * len(fields))field_list = ','.join(fields)sql = f"INSERT INTO {table_name} ({field_list}) VALUES ({placeholders})"try:return self.execute(sql, values)except pymysql.MySQLError as e:if e.args[0] == 1062:logging.warning("重復插入被跳過")else:logging.error("插入數據出錯: %s\n數據: %s", e, item)raisedef table_update(self, table_name, updates: dict, field_where: str, value_where):set_clause = ', '.join([f"{k}=%s" for k in updates])values = list(updates.values()) + [value_where]sql = f"UPDATE {table_name} SET {set_clause} WHERE {field_where}=%s"self.execute(sql, values)

四、多線程測試代碼

以下代碼通過 10 個線程并發對數據庫進行增刪改查,測試連接池的穩定性與日志輸出的整潔性。

import threading
import logging
from CoreUtils.Sql import ConnectionPool# 日志格式配置
logging.basicConfig(level=logging.INFO,format='[%(asctime)s][%(levelname)s][%(threadName)s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S'
)# 初始化連接池
pool = ConnectionPool(host='localhost',database='test_db',user='root',password='your_password',port=3306
)def test_multithread():def thread_task(i):name = f"User-{i}"age = 20 + itry:pool.insert("INSERT INTO test_table (name, age) VALUES (%s, %s)", (name, age))logging.info(f"插入成功: {name}")data = pool.get("SELECT * FROM test_table WHERE name=%s", (name,))logging.info(f"查詢結果: {data}")pool.execute("UPDATE test_table SET age = age + 1 WHERE name = %s", (name,))logging.info("年齡更新完成")updated = pool.get("SELECT * FROM test_table WHERE name=%s", (name,))logging.info(f"更新后數據: {updated}")pool.execute("DELETE FROM test_table WHERE name=%s", (name,))logging.info("刪除完成")pool.table_insert("test_table", {"name": f"{name}_new", "age": age})logging.info("table_insert 成功")exists = pool.table_has("test_table", "name", f"{name}_new")logging.info(f"table_has 檢查: {exists is not None}")pool.table_update("test_table", {"age": 99}, "name", f"{name}_new")logging.info("table_update 完成")except Exception as e:logging.exception("線程異常")threads = []for i in range(10):t = threading.Thread(target=thread_task, args=(i,), name=f"Thread-{i}")threads.append(t)t.start()for t in threads:t.join()logging.info("多線程測試完成")if __name__ == "__main__":test_multithread()

五、準備測試數據表

CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) UNIQUE NOT NULL,age INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

六、運行結果示意

運行后,你將看到類似如下整齊的日志輸出:

在這里插入圖片描述

你可以根據實際項目需要將日志輸出到文件中(通過 filename='xxx.log' 配置 logging.basicConfig())。


七、總結

本文介紹了一個線程安全的 MySQL 連接池封裝方式,并通過多線程場景驗證其并發穩定性。在高并發讀寫、日志整潔輸出、連接復用等方面表現良好,適用于中小型 Python 爬蟲項目中的數據庫訪問層封裝。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78853.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78853.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78853.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML:常用標簽(元素)匯總

文章目錄 一、標簽分類1、塊標簽與行標簽 二、排版標簽三、文本標簽1、常用2、不常用 四、圖片標簽五、超鏈接1、跳轉頁面2、跳轉文件或下載文件3、跳轉到錨點4、喚起本地應用 六、列表七、表格八、表單九、框架十、HTML實體十一、全局屬性十二、meta元信息 一、標簽分類 1、塊…

20250430在ubuntu14.04.6系統上完成編譯NanoPi NEO開發板的FriendlyCore系統【嚴重不推薦,屬于沒苦硬吃】

【開始編譯SDK之前需要更新源】 rootrootubuntu:~/friendlywrt-h3$ sudo apt update 【這兩個目錄你在ubuntu14.04.6系統上貌似git clone異常了】 Y:\friendlywrt-h3\out\wireguard Y:\friendlywrt-h3\kernel\exfat-nofuse 【需要單線程編譯文件系統,原因不明】 Y:…

【AI論文】CipherBank:通過密碼學挑戰探索LLM推理能力的邊界

摘要:大型語言模型(LLMs)已經展現出非凡的能力,尤其是最近在推理方面的進步,如o1和o3,推動了人工智能的發展。盡管在數學和編碼方面取得了令人印象深刻的成就,但在需要密碼學專業知識的領域&…

藝術與科技的雙向奔赴——高一鑫榮獲加州聯合表彰

2025年4月20日,在由M.A.D公司協辦的“智藝相融,共赴價值巔峰”(Academic and Artistic Fusion Tribute to the Summit of Value)主題發布會上,音樂教育與科技融合領域的代表人物高一鑫,因其在數字音樂教育與中美文化交流方面的杰出貢獻,榮獲了圣蓋博市議員Jorge Herrera和爾灣市…

【深度學習的靈魂】圖片布局生成模型LayoutPrompt(1)

🌈 個人主頁:十二月的貓-CSDN博客 🔥 系列專欄: 🏀《深度學習理論直覺三十講》_十二月的貓的博客-CSDN博客 💪🏻 十二月的寒冬阻擋不了春天的腳步,十二點的黑夜遮蔽不住黎明的曙光 目…

Compose筆記(二十)--TextField

這一節主要了解一下Compose的TextField,TextField 是一個用于接收用戶文本輸入的 UI 組件,允許用戶通過鍵盤輸入、編輯或刪除文本。簡單用法總結如下: API value:當前輸入的文本內容。 onValueChange 含義:當用戶輸入文本時觸發的回調函數,參…

在Linux虛擬機下使用vscode,#include無法跳轉問題

總結:需要通過Linux指令來添加編譯器和壓縮文件,解壓,這樣獲得的編譯器會具有可執行權限類似于 -rwxr-xr-x 1 user user 12345 Apr 26 14:22 myscript.sh 如果你直接從window中拖入文件到Linux文件下,你需要自己來再度開啟可編譯…

ArcGIS+GPT:多領域地理分析與決策新方案

技術點目錄 AI大模型應用ArcGIS工作流程及功能prompt的使用技巧AI助力工作流程AI助力數據讀取AI助力數據編輯與處理AI助力空間分析AI助力遙感分析AI助力二次開發AI助力科研繪圖ArcGISAI綜合應用了解更多 ——————————————————————————————————…

基礎術語說明

車間:工廠內集中進行加工或裝配的獨立空間,配備設備、工具及人員,是生產活動的核心載體。 比如裝配車間、總裝車間、油漆車間等 生產線:以流水作業形式將原材料轉化為成品的設備與人員的組合系統,強調連續性和效率。…

Splunk 使用Role 實現數據隔離

很多人知道 Splunk 有很多自帶的Role, 今天我就要說說定制化的Role: 1: 在創建新role 的界面: 2: 在如下的界面,可以定制allow index name: 3: 創建好新Role 后,在SAML 添加新的group 的時候,就可以看到Role 給某個group: 4: 這樣一個特定組的人來申請Splunk 權限,就可…

利用李雅普諾夫穩定性理論設計模型參考自適應系統(2.0)

上一篇介紹了利用李雅普諾夫穩定性理論設計模型參考自適應系統,通過在被控對象前面添加一個可調增益,然后利用李雅普諾夫穩定性理論設計增益的自適應率,使得被控對象輸出與參考模型輸出一致。本文將介紹在系統結構中引入前饋和反饋的結構&…

前端封裝WebSocket工具n

Web API 提供的 WebSocket 類,封裝一個 Socket 類 // socket.js import modal from /plugins/modal const baseURL import.meta.env.VITE_APP_BASE_WS; const EventTypes [open, close, message, error, reconnect]; const DEFAULT_CHECK_TIME 55 * 1000; // 心…

TCP和UDP傳輸層協議

TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是兩種常見的傳輸層協議,它們在網絡通信中發揮著不同的作用。二者在連接建立、可靠性、傳輸效率等方面存在顯著差異,適用于不同的應用場…

空域倫理與AI自主邊界的系統建構

在AI無人系統逐步參與城市空域治理的過程中,系統的“自主性”已不再僅是技術指標,而是直接影響合規性、安全性與社會接受度的倫理邊界議題。AI決策系統是否擁有“強干預能力”?行為觸發責任應歸屬何方?算法可否調優至“自我糾偏”…

在原生代碼(非webpack)里使用iview的注意事項

最近公司在做一個項目,使用的框架是iview,使用過程中同事遇到一些問題,這些問題對于有些同學來說根本就不是問題,但總會有同學需要,為了幫助不太會用的同學快速找到問題,做了如下整理: 下載vue,iview.min.j…

java代碼混淆

生成jar的時候混淆 目前最常用的Proguard,網上有很多介紹的文章,這種安全性較低 對已經生成的jar進行加密 加密庫:https://github.com/li571312729/classfinal 測試對jar進行加密 加密后如果正常調用的話會失敗 加密后jar反編譯查看不到代碼 使用密碼才能調用機…

【Linux】第十三章 訪問Linux文件系統

目錄 1. 存儲設備是什么?怎么理解分區和格式化? 2. 文件系統是什么? 3. 掛載是什么?掛載點是什么? 4. 怎么理解塊設備? 5. 在SATA附加存儲中,第一磁盤上的第一個分區和第二磁盤的第二個分區…

MCP 服務器搭建【stdio 類型】實現上市公司年報查詢總結,配合 Cherry Studio使用簡單

代碼解釋 這段 Python 代碼的主要功能是搭建一個基于 FastAPI 的 MCP 服務器,用于處理通過股票代碼查詢上市公司年報的請求,實現服務器向客戶端的實時消息推送。以下是對代碼各部分的詳細解釋: 完整代碼+使用 Cherry Studio 調用 MCP 服務器的方法,放在文章最后了 1. 導…

第六節:軟件安裝

理論知識 軟件安裝的方式:在 Linux 系統中,常見的軟件安裝方式有源碼安裝、在線安裝、deb 包安裝、RPM 包安裝、使用 Snap 管理軟件包等。不同的安裝方式適用于不同的軟件和場景。源碼安裝:源碼安裝是指從軟件的源代碼開始,進行編…

ubantu部署yolov5(第四集:模型加速)

參考鏈接: GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite TFLite,ONNX,CoreML,TensorRT Export -Ultralytics YOLO Docs 使用Neural Magic 的 DeepSparse 部署YOLOv5 -Ultralytics YOLO 文檔 sparseml/inte…