基礎組件(三):mysql連接池

文章目錄

  • 一、MySQL連接池設計
    • 1. 連接池解決了什么問題?
      • 連接池的作用 (好處)
      • 為什么不創建多條連接而用連接池
    • 2. 同步和異步連接池的區別
      • 同步連接池(場景局限,應用服務器啟動時初始化資源)
      • 異步連接池(應用在服務器啟動后處理業務)
    • 3. 單條MySQL連接過程
    • 4. 連接池的實現
      • 安裝接口庫
      • 異步連接
      • 代碼實現


一、MySQL連接池設計

數據庫連接池是程序啟動時建立足夠的數據庫連接,并將這些連接組成一個連接池,由程序動態地對池中的連接進行申請,使用,釋放。

1. 連接池解決了什么問題?

連接池的作用 (好處)

  • 資源復用
    減少資源浪費,不再頻繁創建和銷毀連接,降低了系統資源的消耗。if不使用連接池,每次數據庫請求都新建一條連接,將耗費系統資源。
  • 更快的系統響應速度
    一次連接的建立和銷毀,可復用同一條連接多次執行SQL語句。
    通過復用連接池中的連接,避免了重復的連接創建過程,大大縮短了數據庫操作的響應時間,在高并發場景下,顯著提升了系統的整體性能。
  • 提升應用穩定性
    連接池可以對連接進行統一管理,當出現連接泄漏(即應用程序獲取連接后未正確歸還)等問題時,連接池能夠進行一定程度的檢測和處理,避免因連接問題導致應用程序崩潰。

為什么不創建多條連接而用連接池

因為同一條數據庫連接上串行執行sql語句的,而并發執行(創建多條連接)sql語句帶來的副作用是需要考慮事務。本質連接池是一個數據庫連接的緩存容器


2. 同步和異步連接池的區別

同步連接池(場景局限,應用服務器啟動時初始化資源)

請添加圖片描述
當前線程從連接池(線程安全)中獲取可用連接( 未被鎖定的連接),描述當前最多允許幾個線程或協程并發使用連接。

異步連接池(應用在服務器啟動后處理業務)

請添加圖片描述
任意線程向連接池投遞SQL語句執行請求,連接池依次從隊列里取任務執行。用戶請求間接(通過異步回調接收數據庫返回)獲取數據庫應
答。描述著當前最多允許幾個連接同時執行 SQL 語句。

  • 獲取返回值
    同步鏈接(Synchronous): 通過 接口的返回值 接受數據庫返回值,主線程會堵塞
    異步連接(Asynchronous): 通過 回調函數 接受數據庫返回值,主線程不會堵塞

3. 單條MySQL連接過程

請添加圖片描述
第一次訪問的時候需要建立連接,但是之后的訪問,均會復用之前的創建的連接,直接執行SQL語句即可.

每次執行一條SQL語句的網絡交互有:
1)TCP建立連接的三次握手(客戶端與mysql服務器的連接基于tcp)
2) MySQL認證的三次握手
3) 真正的SQL執行
4) MySQL的關閉
5) TCP的四次揮手關閉

連接池的運行流程
它在系統初始化時創建一定數量的數據庫連接對象,并將這些連接維護在一個池中。當應用程序需要與 MySQL 數據庫進行交互時,無需重新創建新的連接,而是從連接池中獲取一個已有的連接;
當操作完成后,再將該連接歸還到連接池中,以便后續其他請求復用。這種方式大大減少了連接創建和銷毀的開銷。

  • MySQL連接的要素:主機IP、主機端口、用戶名、密碼
    連接池連接數公式: 連接數=(核心數*2)+有效磁盤數
    連接池與線程池區別:連接池被動使用,線程池是主動不斷的從隊列中去執行任務

4. 連接池的實現

優秀筆記: MySQL連接池使用步驟

安裝接口庫

//MYSQL的驅動
libmysqlclient     //純c實現
libmysqlcppconn    //c++實現,使用了異常機制
//阻塞io=================================//安裝 libmysqlcppconn
sudo apt-get install libmysqlcppconn-dev**頭文件: /usr/include/cppconn/*.h
**庫文件: /uer/lib/x86_64-linux-gnu/libmysqlcppconn.alibmysqlcppconn.so

異步連接

基于連接去執行命令(send)和等待結果(recv)的過程是一個耗時操作,考慮使用線程池去實現。

因為線程要獲取,命令的返回值結果作為執行命令的參數,所以我們引入future-promise,來獲取結果

主線程創建 promise 并獲取 future。
新線程執行 database_query(),查詢完成后調用 prom.set_value(result) 傳遞查詢結果。
主線程阻塞等待 fut.get() 獲取 SQL 查詢結果

代碼實現

//MySQLConnPool.hnamespace sql {class ResultSet;
}
//前置聲明  防止依賴過深
class MySQLConn;
template <typename T>
class BlockingQueue;class SQLOperation;class MySQLConnPool {
public://獲取單例static MySQLConnPool *GetInstance(const std::string &db);void InitPool(const std::string &url, int pool_size);//輸入sql語句,執行對應的回調函數QueryCallback Query(const std::string &sql, std::function<void(std::unique_ptr<sql::ResultSet>)> &&cb);private:MySQLConnPool(const std::string &db) : database_(db) {}~MySQLConnPool();std::string database_;std::vector<MySQLConn *> pool_;//因為數據庫有多個,但是我們每次只訪問一個,所以用單例模式//一個數據庫對應一個單例,所以用unordered_map存儲static std::unordered_map<std::string, MySQLConnPool *> instances_;//阻塞隊列 存儲sql操作BlockingQueue<SQLOperation *> *task_queue_;
};//MySQLConn.h//前置聲明
namespace sql 
{class Driver;class Connection;class SQLException;class ResultSet;
}class MySQLWorker;template <typename T>
class BlockingQueue;class SQLOperation;struct MySQLConnInfo {explicit MySQLConnInfo(const std::string &info, const std::string &db);std::string user;std::string password;std::string database;std::string url;
};class MySQLConn {
public:MySQLConn(const std::string &info, const std::string &db, BlockingQueue<SQLOperation *> &task_queue);~MySQLConn();//自定義 連接函數,防止連接中斷int Open();void Close();//執行sql語句sql::ResultSet* Query(const std::string &sql);private://異常處理函數void HandlerException(sql::SQLException &e);//sql驅動,連接sql::Driver *driver_;sql::Connection *conn_;//對應的線程對象MySQLWorker *worker_;MySQLConnInfo info_;
};//MySQLWorker.hclass MySQLConn;template <typename T>
class BlockingQueue;class SQLOperation;class MySQLWorker {
public://傳入連接線程,和執行命令隊列MySQLWorker(MySQLConn *conn, BlockingQueue<SQLOperation *> &task_queue);~MySQLWorker();void Start();void Stop();private://工作線程void Worker();MySQLConn *conn_;std::thread worker_;//任務隊列BlockingQueue<SQLOperation *> &task_queue_;
};//SQLOperation.hnamespace sql
{class ResultSet;
}class MySQLConn;class SQLOperation {
public:explicit SQLOperation(const std::string &sql) : sql_(sql) {}void Execute(MySQLConn *conn);std::future<std::unique_ptr<sql::ResultSet>> GetFuture() {return promise_.get_future();}private:std::string sql_;std::promise<std::unique_ptr<sql::ResultSet>> promise_;
};//QueryCallback.hnamespace sql
{class ResultSet;
}class QueryCallback {
public:QueryCallback(std::future<std::unique_ptr<sql::ResultSet>> &&future, std::function<void(std::unique_ptr<sql::ResultSet>)> &&cb): future_(std::move(future)), cb_(std::move(cb)){}bool InvokeIfReady() {if (future_.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {cb_(std::move(future_.get()));return true;}return false;}
private:std::future<std::unique_ptr<sql::ResultSet>> future_;std::function<void(std::unique_ptr<sql::ResultSet>)> cb_;
};//AsyncProcessor.hclass QueryCallback;
class AsyncProcessor
{
public:void AddQueryCallback(QueryCallback &&query_callback);void InvokeIfReady();private:std::vector<QueryCallback> pending_queries_;
};

優秀筆記:
1. 池式結構–MYSQL連接池
2. mysql連接池的實現
3. MySQL連接池原理及設計
參考學習:https://github.com/0voice

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

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

相關文章

FI文件包含漏洞

本地文件包含&#xff08;LFI&#xff09;文件包含開發人員將可重復使用的內容寫到單個文件中&#xff0c;使用時直接調用此文件&#xff0c;無需再次編寫&#xff0c;這種調用文件的過程一般被稱為文件包含。這樣編寫代碼能減少代碼冗余&#xff0c;降低代碼后期維護難度&…

rapidocr_web v1.0.0發布了

建立RapidOCRWeb獨立倉庫 終于將web這塊代碼移了出來&#xff0c;成立了獨立倉庫RapidOCRWeb (https://github.com/RapidAI/RapidOCRWeb )。這樣以來&#xff0c;RapidOCR倉庫下的各個衍生項目均有自己的獨立倉庫&#xff0c;可以單獨控制發版和維護。這也算是為RapidOCR減負了…

Arduino IDE離線安裝ESP8266板管理工具

文章目錄概要官網地址開發板管理地址安裝ESP8266開發板支持離線安裝額外記錄NODE啟動服務概要 Arduino IDE離線安裝ESP8266板管理工具&#xff0c;在線安裝因為網絡或者https的問題不能安裝 官網地址 Adruino&#xff1a;https://www.arduino.cc/ ESP8266項目&#xff1a;<…

兩款免費數據恢復軟件介紹,Win/Mac均可用

數據已成為我們生活與工作中不可或缺的重要組成部分。無論是珍貴的家庭照片、關鍵的工作文檔&#xff0c;還是重要的學習資料&#xff0c;都以數據的形式存儲在各類設備中。然而&#xff0c;數據丟失的情況卻時常發生&#xff0c;可能是誤操作刪除&#xff0c;可能是設備意外損…

Java開發中敏感信息加密存儲全解析:筑牢數據安全防線

Java開發中敏感信息加密存儲全解析&#xff1a;筑牢數據安全防線 一、引言 1.1 敏感信息存儲的現狀與挑戰 在數字化時代&#xff0c;數據已然成為企業和組織的核心資產之一&#xff0c;而敏感信息的存儲更是重中之重。從日常的用戶登錄密碼、身份證號碼&#xff0c;到金融領域…

list的使用和模擬

(一)list的了解 (1)簡單了解 list的文檔介紹 list是基于雙向鏈表的序列式容器&#xff0c;支持雙向迭代和任意位置的常數時間插入刪除&#xff0c;相比 array、vector 等容器在這類操作上更高效&#xff0c;但不支持隨機訪問&#xff08;訪問需線性遍歷&#xff09;且因額外…

Docker 初學者需要了解的幾個知識點 (五):建容器需要進一步了解的概念

之前在《Docker 初學者需要了解的幾個知識點》幾篇文章里&#xff0c;我們梳理了 Docker 的核心概念&#xff08;如鏡像、容器、網絡等&#xff09;&#xff0c;但在實際搭建 ThinkPHP 容器環境時&#xff0c;又遇到了一些更具體的術語和配置場景。這些內容和實操結合緊密&…

【數據結構】棧的順序存儲(整型棧、字符棧)

【數據結構】棧的順序存儲&#xff08;整型棧、字符棧&#xff09;一、棧的結構定義二、字符棧的初始化、入棧、出棧、判斷是否棧為空、獲取棧頂元素、獲取棧的當前元素個數等操作三、整型棧的初始化、入棧、出棧、判斷是否棧為空、獲取棧頂元素、獲取棧的當前元素個數等操作一…

【大模型實戰】向量數據庫實戰 - Chroma Milvus

在 RAG&#xff08;檢索增強生成&#xff09;場景中&#xff0c;非結構化數據&#xff08;文本、圖像等&#xff09;的高效檢索是核心需求。傳統關系型數據庫難以勝任&#xff0c;而向量數據庫通過將數據轉化為向量、基于相似度快速匹配&#xff0c;成為 RAG 的關鍵支撐。本文聚…

pytorch程序語句固定開銷分析

深入探索PyTorch與Python的性能微觀世界&#xff1a;量化基礎操作的固定開銷 在深度學習的性能優化工作中&#xff0c;開發者通常將目光聚焦于模型結構、算法效率和并行計算策略。然而&#xff0c;在這些宏觀優化的背后&#xff0c;構成我們代碼的每一條基礎語句——無論是PyTo…

ABP VNext + CloudEvents:事件驅動微服務互操作性

ABP VNext CloudEvents&#xff1a;事件驅動微服務互操作性 &#x1f680; &#x1f4da; 目錄ABP VNext CloudEvents&#xff1a;事件驅動微服務互操作性 &#x1f680;一、引言 ??? TL;DR&#x1f4da; 背景與動機&#x1f3d7;? 整體架構圖二、環境準備與依賴安裝 &am…

軟件測試測評公司關于HTTP安全頭配置與測試?

瀏覽器和服務器之間那幾行看不見的HTTP安全頭配置&#xff0c;往往是抵御網絡攻擊的關鍵防線。作為軟件測試測評公司&#xff0c;我們發現超過六成的高危漏洞源于安全頭缺失或誤配。別小看這些響應頭&#xff0c;它們能直接掐斷跨站腳本、點擊劫持、數據嗅探的攻擊路徑。五條命…

Mysql集成技術

目錄 mysql的編譯安裝與部署 1.編譯安裝mysql 2.部署mysql mysql主從復制 什么是mysql主從復制&#xff1f; 1.配置master 2.配置slave 3.存在數據時添加slave2 4.GTID模式 什么是GTID模式&#xff1f; 配置GTID 5.延遲復制 6.慢查詢日志 核心作用 開啟慢查詢日志…

《MySQL進階核心技術剖析(一): 存儲引擎》

目錄 一、存儲引擎 1.1 MySQL體系結構 1.2 存儲引擎介紹 1). 建表時指定存儲引擎 2). 查詢當前數據庫支持的存儲引擎 1.3 存儲引擎特點 1.3.1 InnoDB 1.3.2 MyISAM 1.3.3 Memory 1.3.4 區別及特點 1.4 存儲引擎選擇 一、存儲引擎 1.1 MySQL體系結構 1). 連接層 最上…

sqli-labs:Less-26關卡詳細解析

1. 思路&#x1f680; 本關的SQL語句為&#xff1a; $sql"SELECT * FROM users WHERE id$id LIMIT 0,1";注入類型&#xff1a;字符串型&#xff08;單引號包裹&#xff09;、GET操作提示&#xff1a;參數需以閉合關鍵參數&#xff1a;id php輸出語句的部分代碼&am…

Spring Boot 的事務注解 @Transactional 失效的幾種情況

開發中我們經常會用到 Spring Boot 的事務注解&#xff0c;為含有多種操作的方法添加事務&#xff0c;做到如果某一個環節出錯&#xff0c;全部回滾的效果。但是在開發中可能會因為不了解事務機制&#xff0c;而導致我們的方法使用了 Transactional 注解但是沒有生效的情況&…

#C語言——刷題攻略:牛客編程入門訓練(四):運算

&#x1f31f;菜鳥主頁&#xff1a;晨非辰的主頁 &#x1f440;學習專欄&#xff1a;《C語言刷題合集》 &#x1f4aa;學習階段&#xff1a;C語言方向初學者 ?名言欣賞&#xff1a;"代碼行數決定你的下限&#xff0c;算法思維決定你的上限。" 目錄 1. BC25 牛牛買電…

阻抗分析中的軟件解調計算

接上篇 重溫無功功率測量-CSDN博客 已知被測阻抗兩端電壓與流過 通過兩個ADC同步采集到。 激勵頻率10k, 采樣率1M, 每周期100個點 關鍵是:采樣率除以激勵頻率, 得是4的倍數... 所以ADC不能自由運行, 得用一個timer來觸發. 因為要進行同相分量正交分量計算。 1&#xff1a;直…

ubuntu 鏡像克隆

一、克隆 1、準備 一個u盤&#xff08;制作啟動盤&#xff09; 一個移動固態硬盤&#xff08;大于要克隆系統盤的1.2倍&#xff09; 2、使用 rufus生成系統啟動盤 &#xff08;1&#xff09;下載ubuntu iso 桌面版 https://cn.ubuntu.com/download &#xff08;2&#x…

Axure下拉菜單:從基礎交互到高保真元件庫應用

在Web端產品設計中&#xff0c;下拉菜單&#xff08;Dropdown Menu&#xff09; 是用戶與系統交互的核心組件之一&#xff0c;它通過隱藏次要選項、節省頁面空間的方式&#xff0c;提升信息密度與操作效率。無論是基礎下拉菜單、圖標式下拉菜單&#xff0c;還是復雜的多級下拉菜…