news 2026/8/10 21:41:56

MySQL异步连接池的学习(五)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL异步连接池的学习(五)

一、异步连接池

1.1、为什么需要异步连接池

在高并发场景下,同步连接池的性能瓶颈主要体现在两个方面:

  • 阻塞等待:在获取空闲连接时,如果当前没有可用连接,线程会阻塞等待。在高负载情况下,这会导致大量线程处于等待状态,从而降低整体性能。

  • 频繁的数据库操作:在高并发的应用中,每个请求都需要与数据库进行交互,而每次交互都涉及到网络通信的开销。特别是在使用同步方式时,这些开销会被放大,因为每次操作都会导致线程阻塞。

为了解决这些问题,可以考虑实现一个基于事件驱动或非阻塞IO模型的异步连接池。这样的设计可以减少线程数量,提高资源利用率,同时通过非阻塞的方式处理I/O操作,从而提高系统的吞吐量和响应速度。

1.2、异步连接池的设计

  1. 完全异步连接池:官方给的相关驱动中,没有提供异步驱动,如果需要实现异步连接池,就需要自己实现MySQL协议的解析和封装。难度较大,需要深入了解MySQL协议和网络编程,还要考虑系统平台支持哪些异步操作,C/C++在不同的系统平台,所支持的异步操作也不太一样。

    大致流程:

  2. 半异步连接池: 基于线程池的思想,可以将官方给的同步驱动放入专门的线程池中,通过任务队列模拟异步行为。

    大致流程:

1.3、半异步连接池实现

基于上面的思路,可以这样再进一步优化下,提高性能,让每个线程都有自己专门的任务队列,而不是公共的任务队列,这样能减少锁的开销,但会增加内存的开销,使用时需权衡下利弊。

运行环境:Linux系统,C++17,具备boost库,以及MySQL官方给出的驱动

本以为就在线程池的基础上添加MySQL的驱动,就完事,没想到并发场景下,各种异常,代码是越改越多,索性重新设计

多个工作线程异步执行一条SQL语句,就这样了。

设计两个类,一个是连接池类,一个是工作线程类;连接池包含多个工作线程,每个工作线程持有一个数据库连接,避免多个线程共享同一个数据库连接,保证线程安全,也保证每个工作线程独立工作互不干扰。

class ConnectionPool { public: using Callback = std::function<void(std::shared_ptr<sql::ResultSet>)>; struct Task { std::string query; Callback callback; }; ConnectionPool(const std::string& host, const std::string& user, const std::string& password, const std::string& database, size_t pool_size = 2); ~ConnectionPool(); void execute(const std::string& query, Callback callback); void start_health_check(); private: class Worker; // 前向声明 void health_check(); void shutdown(); ... }; // 工作线程类,负责自己的线程管理(处理任务),以及对SQL语句的执行 class ConnectionPool::Worker { public: void add_task(Task task); bool check_connection(); private: void run(); void execute_task(const Task& task); void connect(); void reconnect(); void stop(); ConnectionPool& m_pool; std::queue<Task> m_queue; ... };

监控连接池的状态,目前未添加定时任务,让其定时检查连接池的健康状态

void ConnectionPool::start_health_check() { if (m_health_check_running) return; m_health_check_running = true; m_health_thread = std::thread(&ConnectionPool::health_check, this); std::cout << "Health check started\n"; } void ConnectionPool::health_check() { while (m_health_check_running) { std::this_thread::sleep_for(15s); if (m_shutdown) break; size_t healthy_count = 0; for (auto& worker : m_workers) { if (worker->check_connection()) { healthy_count++; } } std::cout << "Health check: " << healthy_count << "/" << m_workers.size() << " workers healthy\n"; } }

以这张表来进行测试:



二、总结

2.1、同步连接池的适用场景

  1. 业务逻辑简单
  2. 并发量小(<1000)
  3. 对性能要求不高

2.2、异步连接池的适用场景

  1. 业务逻辑复杂
  2. 高并发场景(>1000)
  3. 对性能要求高

2.3、在一些大型项目中,更多的是采用混合使用

比如一些游戏服务器中,对玩家的实时操作采取异步连接池,后台管理操作采用同步连接池方案,这样既能保证高并发场景下的性能,也能满足后台管理操作的实时性。

三、补充

在使用异步连接池接入服务器时,发现些问题,并尝试让AI修复了

3.1、异步连接池迭代 2.0 说明

1. 问题修复清单

  • 伪异步与数据竞争:本质仍为半异步(线程池模拟)。引入m_conn_mtx互斥锁,在check_connection()execute_task()reconnect()中加锁,彻底解决健康检查线程与工作线程并发访问m_conn的数据竞争问题。
  • 队列无限增长与边界异常:在addTask()中增加max_queue_size校验,超限直接拒绝任务返回false;在initialize()submitTask()中增加pool_size == 0m_workers.empty()的防御性检查。
  • 任务类型单一:在Task结构体中引入TaskType枚举(QUERY,UPDATE,EXECUTE),在execute_task中根据类型分别调用executeQueryexecuteUpdate,支持规范的写操作与事务。
  • Session 状态丢失:新增resetSession()方法,在connect()reconnect()成功后调用,强制恢复AUTOCOMMIT=1和字符集等参数。
  • 裸 SQL 与回调线程安全:架构上明确要求业务层使用sql::PreparedStatement防注入;在注释中强调回调函数运行在 Worker 线程,外部回调(如修改网络连接状态)必须通过TcpConnection::send()等线程安全接口回投,禁止直接操作共享资源。

Code

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/10 21:41:48

10分钟上手GeoFire for Java:从安装到实现位置查询的完整教程

10分钟上手GeoFire for Java&#xff1a;从安装到实现位置查询的完整教程 【免费下载链接】geofire-java GeoFire for Java - Realtime location queries with Firebase 项目地址: https://gitcode.com/gh_mirrors/ge/geofire-java GeoFire for Java 是一款基于 Firebas…

作者头像 李华
网站建设 2026/8/10 21:35:43

spreadsheet-reader API详解:Sheets()与ChangeSheet()函数的高级应用

spreadsheet-reader API详解&#xff1a;Sheets()与ChangeSheet()函数的高级应用 【免费下载链接】spreadsheet-reader A PHP spreadsheet reader (Excel XLS and XLSX, OpenOffice ODS, and variously separated text files) with a singular goal of getting the data out, e…

作者头像 李华
网站建设 2026/8/10 21:34:20

VimPlus终极指南:3步打造专业级Vim开发环境

VimPlus终极指南&#xff1a;3步打造专业级Vim开发环境 【免费下载链接】vimplus :rocket:An automatic configuration program for vim 项目地址: https://gitcode.com/gh_mirrors/vi/vimplus VimPlus是一款革命性的Vim自动配置程序&#xff0c;专为开发者和程序员设计…

作者头像 李华
网站建设 2026/8/10 21:32:34

终极解决方案:如何免费解除Windows远程桌面多用户限制

终极解决方案&#xff1a;如何免费解除Windows远程桌面多用户限制 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾经因为Windows远程桌面只能一个人连接而感到困扰…

作者头像 李华
网站建设 2026/8/10 21:32:26

Docker面试通关秘籍:DevOps Interview-Guide中的高频问题与答案

Docker面试通关秘籍&#xff1a;DevOps Interview-Guide中的高频问题与答案 【免费下载链接】DevOps-Interview-Guide DevOps Interview Guide 项目地址: https://gitcode.com/GitHub_Trending/de/DevOps-Interview-Guide Docker作为DevOps技术栈的核心工具&#xff0c…

作者头像 李华