文章目录

  • 一、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;还是复杂的多级下拉菜…