当前位置: 首页 > news >正文

池化思想-Mysql异步连接池

前言

        继前文池化思想-线程池的后续,继续学习池化思想,本例为Mysql连接池。根据前文针对池化思想的概述,池化的目的在于“复用”。“复用”达到效率的高低要看对于“工具”的创建代价。如果新创建一个“工具”所需付出的代价越高那么在控制好复用代价的前提下能极大提高整体效率。对于Mysql连接池作为一个符合上述内容的例子,后文介绍如何一个简单的Mysql连接池。

一、Mysql 连接过程

        本文介绍Mysql连接池之前先介绍一下Mysql连接建立的过程。因为连接池需要维护的是Mysql连接,因此理解Mysql连接建立过程后才能理解为什么Mysql连接池复用Mysql连接能够提效。

        对于Mysql连接主要的建立方式很多,包括:Unix套接字、内存共享、命名管道、TCP/IP套接字等。

        其中除了TCP/IP套接字外,其他几种都是基于进程间通信涵盖的内容,因此需要满足一个前置条件就是:Mysql客户端和服务端需要在一台物理机上。虽然TCP/IP通信也可用在同一机器上的进程间通信,但是此方式提供跨机器进行服务访问就是其他方式不具备的了。这也是最常用的使用方式。

        既然是基于TCP连接实现的Mysql服务端客户端连接,因此在Mysql连接正式建立之前需要建立起TCP连接。对于TCP连接建立的开销,可以查看之前的文章,三次握手的开销。这已经是一部分开销了,后续还需要握手认证,之后才正式建立了一条Mysql连接,客户端可以向服务端发送需要执行的操作命令。其中大概的流程如下图:

        针对上述内容的分析,对于Mysql连接池的建立,可以复用Mysql连接,一次创建,节省后续多次建立Mysql连接的开销,从而达到提升整体效率的目的。

二、同步连接池 VS 异步连接池

        既然想要创建一个Mysql连接池,对于Mysql连接池有同步与异步之分。对于同步与异步的区别,关键在于调用方线程在“提交任务”与“获取结果”这两个阶段的行为方式。下文分别介绍同步连接池与异步连接池:

1、同步连接池使用过程

  • 调用方行为: 调用方线程执行的是“同步阻塞式”的操作流程。

  • 获取连接: getConnection() 调用会阻塞线程,直到拿到一个可用连接(或超时/失败)。

  • 执行SQL: 调用方线程使用获得的连接执行 executeQuery, executeUpdate 等操作。

  • 等待结果: 这些执行SQL的方法会阻塞调用方线程,直到数据库服务器返回最终结果(数据行、影响行数、错误等)。

  • 全过程: 调用方线程在整个数据库操作的生命周期(获取连接 -> 发送SQL -> 等待/处理结果 -> 释放连接)中都是被独占且阻塞的。它不能在这段时间内做任何其他工作

2、异步连接池使用过程

  • 调用方行为: 调用方线程执行的是“异步非阻塞式”的操作流程。

  • 提交任务: 调用方线程发起一个数据库操作请求(可能包含SQL语句和参数)。这个请求通常是:

    • 向连接池“预约”一个连接(非阻塞获取)。

    • 直接将SQL任务提交给一个更高层次的异步接口(该接口内部管理连接池)。

  • 非阻塞: 提交请求的方法(如返回 Future, CompletableFuture 或接受回调的方法)会立即返回,不会阻塞调用方线程。调用方线程可以立即去做其他事情(处理其他请求、计算等)。

  • 连接池/驱动工作: 连接池在后台处理连接获取(如果需要等待,也是在后台线程或事件循环中等待,不阻塞调用方线程)。然后驱动使用这个连接异步地、非阻塞地将SQL发送到数据库服务器,并注册一个监听器等待响应。

  • 结果返回: 当数据库服务器返回结果时:

    • 回调 (Callback): 预先注册的回调函数会被调用(通常在某个特定的事件循环线程或线程池中),参数里包含结果或错误。

    • Future/Promise: 之前返回的 Future / CompletableFuture 会被完成(complete(result)completeExceptionally(error))。调用方可以在之后的某个时间点(需要结果时)调用 future.get()(这会阻塞,但通常避免)或者更优雅地使用 thenApply, thenAccept, thenCompose 等链式方法注册后续处理逻辑(非阻塞)。

  • 全过程: 调用方线程只负责提交任务和(稍后)处理结果通知。任务的实际执行(连接获取、网络IO、数据库处理、结果接收)都是在后台线程、事件循环或数据库驱动内部异步完成的,不会阻塞调用方线程

3、同步 VS 异步

        对于上述内容的理解可知:对于同步于异步而言,异步方式效率更高但是实现方式更复杂,流程上更加繁杂对于C++而言需要基于回调函数/Future。同步方式编程模型更简单直观,但是并发能力不如异步方式。后续将设计一个Mysql异步连接池。

三、简单异步连接池设计

        实现一个Mysql连接池,其中的关键主体为Mysql连接,同时需要实现为异步连接池,所以对于“Mysql执行命令的提交”和“Mysql返回结果的获取”这两个任务阶段应该是异步实现的。所以仍复用上文单队列线程池的思想,一个线程对应一个Mysql连接,基于生产者消费者模型,连接池中创建多个线程对应多个Mysql连接,调用方作为生产者提交任务至阻塞队列,连接池中线程作为消费者消费阻塞队列中的任务。根据上述任务执行流程大概架构图如下:

        其中对于上述设计中,有一个点是没有提现到图中的,就是调用方如何获取到Mysql执行结果。对于该功能的实现通过C++11中std::future和std::promise机制实现。即在需要执行的任务对象中设置一个promise,当任务执行完成后将返回的执行结果赋值给futrue。后续调用方就可以在任务执行完成之后通过future获取到最终的执行结果。


        更多资料:0voice · GitHub

http://www.dtcms.com/a/270677.html

相关文章:

  • 教育行业可以采用Html5全链路对视频进行加密?有什么优势?
  • 高通 QCS6490PI 集群架构支撑 DeepSeek 模型稳定运行的技术实现
  • upload-labs靶场通关详解:第19关 条件竞争(二)
  • Java-----韩顺平单例设计模式学习笔记
  • java项目maven编译的时候报错:Fatal error compiling: 无效的标记: --release
  • 【计算机组成原理——知识点总结】-(总线与输入输出设备)-学习笔记总结-复习用
  • Caffeine的tokenCache与Spring的CaffeineCacheManager缓存区别
  • uniapp,Anroid10+版本如何保存图片并删除
  • 缓存三大问题详解与工业级解决方案
  • 视频音频转换器V!P版(安卓)安装就解锁V!P!永久免费使用!
  • 【RK3568+PG2L50H开发板实验例程】FPGA部分 | DDR3 读写实验例程
  • 创客匠人:在 IP 变现浪潮中,坚守知识变现的本质
  • 飞算AI-idea强大的AI工具
  • 二分查找篇——在排序数组中查找元素的第一个和最后一个位置【LeetCode】
  • 如何把一个多行的RAS key放到环境变量中?
  • 最新全开源礼品代发系统源码/电商快递代发/一件代发系统
  • 红宝书单词学习笔记 list 26-50
  • 71、【OS】【Nuttx】【启动】启动函数分析
  • 股权结构解析
  • 首批 | 云轴科技ZStack加入施耐德电气技术本地化创新生态
  • 微算法科技从量子比特到多级系统,Qudits技术革新引领量子计算新时代
  • 从零开始学前端html篇2
  • Redis:分组与设备在 Redis 中缓存存储设计
  • K线训练关键代码
  • Laravel 动态生成 PDF:基于 KnpSnappy 实现多公司页眉页脚差异化配置
  • C++如何进行性能优化?
  • 安卓设备信息查看器 - 源码编译
  • PlantUML 在 IDEA 中文版中的安装与使用指南
  • Vim 编辑器常用操作详解(新手快速上手指南)
  • LKT4304稳定可靠高兼容性国产安全加密芯片