mysql连接池

news2024/11/24 3:46:01
MySQL连接池
什么是数据库连接池?

​ 定义:数据库连接池(Connection pooling)是程序启动时建立一定数量的数据库连接,并将这些连接组成 一个连接池,由程序动态地对池中的连接进行申请,使用,释放。

​ **个人理解:**创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度, 还更加安全可靠。 这里讲的数据库,不单只是指Mysql,也同样适用于Redis。

为什么使用数据库连接池
  1. 资源复用:由于数据库的连接得到的复用,避免创建和销毁连接的性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。
  2. 更快的系统响应速度:数据库连接池在初始化后,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了从数据库连接初始化和释放过程的开销,从而缩减了系统整体响应时间。
  3. 统一的连接管理,避免数据库连接泄露:在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄露。
不使用连接池执行一条sql语句的过程
  1. TCP建立连接的三次握手(客户端与MySQL服务器的连接基于TCP协议)
  2. MySQL认证的三次握手
  3. 真正的SQL执行
  4. MySQL的关闭
  5. TCP的四次挥手关闭
    在这里插入图片描述

优点:实现简单

缺点: 网络IO较多 带宽利用率低 QPS较低 应用频繁低创建连接和关闭连接,导致临时对象较多,带来更多的内存碎片 在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)

使用连接池执行一条sql语句的过程

第一次访问的时候,需要建立连接。 但是之后的访问,均会复用之前创建的连接,直接执行SQL语句。

数据库连接池运行机制

从连接池获取或创建可用连接; 使用完毕之后,把连接返回给连接池; 在系统关闭前,断开所有连接并释放连接占用的系统资源;

线程池设计要点

使用连接池需要预先建立数据库连接。

线程池设计思路:

  1. 连接到数据库,涉及到数据库ip、端口、用户名、密码、数据库名字等;

    1. 配置最小连接数和最大连接数

    2. 需要一个队列管理他的连接,比如使用list;

  2. 连接的操作,每个连接对象都是独立的连接通道,它们是独立的

  3. 获取连接对象:

  4. 归还连接对象;

  5. 连接池的名字

连接池设计逻辑
  1. 构造函数

​

  1. 初始化

​

  1. 请求获取连接

​

  1. 归还连接

​

  1. 析构函数

​

  1. 连接池名

​

#include <list>
#include <string>
#include <mutex>
#include <mysql/mysql.h>
#include <queue>
#include <iostream>
#include <condition_variable>

using namespace std;

class MySqlPool
{
public:
    MySqlPool(string pool_name, string db_server_ip, uint16_t db_server_port, string db_name, 
                                        string db_user, string db_password, int maxSize = 10) 
            : m_pool_name(pool_name), m_db_server_ip(db_server_ip), m_db_server_port(db_server_port), m_db_name(db_name), 
            m_db_user(db_user), m_db_password(db_password), maxSize(maxSize) {}

    void Init() {
        for (int i = 0; i < maxSize; ++i) {
            m_free_pool.emplace_back(createConnection());
        }
    }

    std::shared_ptr<MYSQL> getConn(size_t time_out_time) {
        std::unique_lock<std::mutex> lock(m_mutex);

        // 没有可用连接时
        if (m_free_pool.empty()) {
            // 根据当前连接数选择创建或等待
            if (curSize == maxSize) {
                // 等待且未设置超时时间
                if (time_out_time <= 0) {
                    m_cond.wait(lock, [this] {
                        return (!m_free_pool.empty());
                    });
                } else {
                    m_cond.wait_for(lock, std::chrono::milliseconds(time_out_time), [this] {
                        return (!m_free_pool.empty());
                    });
                    // 超时后再次检查
                    if (m_free_pool.empty()) {
                        return nullptr;
                    }
                }
            } else {
                // 未达到最大连接数
                std::shared_ptr<MYSQL> conn = createConnection();
                m_free_pool.push_back(conn);
                curSize++;
            }
        }
        std::shared_ptr<MYSQL> conn = m_free_pool.front();
        m_free_pool.pop_front();
        m_busy_pool.push_back(conn);
        return conn;
    }

    void returnConn(std::shared_ptr<MYSQL> conn) {
        // 是否已归还
        std::unique_lock<std::mutex> lock(m_mutex);
        list<std::shared_ptr<MYSQL>>::iterator it = m_free_pool.begin();
        for (; it != m_free_pool.end(); it++) {
            if (*it == conn) {
                cout << "Return failed." << endl;
                return;
            }
        }
        m_busy_pool.remove(conn);
        m_free_pool.push_back(conn);
        m_cond.notify_one();
    }

private:
    string m_pool_name;
    string m_db_server_ip;
    uint16_t m_db_server_port;
    string m_db_name;
    string m_db_user;
    string m_db_password;

    int maxSize;
    int curSize;
    
    list<std::shared_ptr<MYSQL>> m_free_pool;
    list<std::shared_ptr<MYSQL>> m_busy_pool;

    std::mutex m_mutex;
    std::condition_variable m_cond;

    std::shared_ptr<MYSQL> createConnection() {
        MYSQL* conn = mysql_init(nullptr);
        if (!mysql_real_connect(conn, m_db_server_ip.c_str(), m_db_user.c_str(), m_db_password.c_str(), m_db_name.c_str(), 
            m_db_server_port, nullptr, 0))
        {
            std::cerr << "mysql connection error: " << mysql_error(conn) << endl;
            mysql_close(conn);
            return nullptr;
        }
        // 自定义删除器
        return std::shared_ptr<MYSQL>(conn, [](MYSQL* p) {
            mysql_close(p);
        });
    }
};

int main() {
    MySqlPool pool("mysql_pool", "127.0.0.1", 3306, "char", "ningao", "ning1020", 10);
    auto conn = pool.getConn(100);
    if (conn) {
        // 执行你的MySQL操作
    }

    pool.returnConn(conn);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2188401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML:相关概念以及标签

目录 什么是网页? 什么是HTML语言? 语法规范 HTML基本结构标签 DOCTYPE,lang以及字符集 HTML常用标签 5>图像标签(重要) 除此之外还有几个调整图片属性的标签 图像标签总结 什么是网页? 我们平时使用电脑和手机都是离不开网站和网页的,那么什么是网页呢?什么又是网…

Yolov8改进轻量级网络Ghostnetv2

1,理论部分 轻量级卷积神经网络 (CNN) 专为移动设备上的应用程序而设计,具有更快的推理速度。卷积运算只能捕获窗口区域中的局部信息,这会阻止性能进一步提高。将自我注意引入卷积可以很好地捕获全局信息,但会在很大程度上阻碍实际速度。在本文中,我们提出了一种硬件友好…

【技术分析】嘉楠科技SoC芯片K230

概述 K230是嘉楠科技Kendryte系列AIoT芯片中的最新一代SoC芯片&#xff0c;该芯片采用全新的多异构单元加速计算架构&#xff0c;集成的玄铁C908具有2个高能效RISCV计算核心&#xff0c;内置新一代KPU&#xff08;Knowledge Process Unit&#xff09;智能计算单元&#xff0c;…

【cpp/c++ summary 工具】 Hunter 报错 CMake hunter error: Unexpected MSVC_VERSION

原因&#xff1a;使用的MSVC编译器版本较高&#xff0c;而Hunter版本较低&#xff0c;可在https://github.com/cpp-pm/hunter/releases配置高版本Hunter # HunterGate( # URL "https://github.com/cpp-pm/hunter/archive/v0.23.297.tar.gz" # SHA1 "33…

【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem:

使用git clone 时报错unable to access xxx: SSL certificate problem: 这个报错通常是由于SSL证书问题引起的。通常可以按照以下步骤进行排查&#xff1a; 检查网络连接&#xff1a;确保你的网络连接正常&#xff0c;可以访问互联网。尝试使用其他网站或工具测试网络连接是否正…

netty之Netty集群部署实现跨服务端通信的落地方案

前言 在一些小型用户体量的socket服务内&#xff0c;仅部署单台机器就可以满足业务需求。但当遇到一些中大型用户体量的服务时&#xff0c;就需要考虑讲Netty按照集群方式部署&#xff0c;以更好的满足业务诉求。但Netty部署集群后都会遇到跨服务端怎么通信&#xff0c;也就是有…

【PS】删除自定义形状,添加自定义形状

删除自定义形状 在这里选择删除形状为灰色的时候&#xff0c;是不能直接删除的&#xff0c;需要打开形状窗口后才能删除。 找到形状窗口&#xff0c;打开它 然后就可以删除形状了。 导入形状 右键&#xff0c;导入形状 选择你要导入的形状包&#xff08;我这个是某宝买…

Stable Diffusion绘画 | 来训练属于自己的模型:秋叶训练器使用

花了不少时间搜索尝试&#xff0c;都没有找到解决上一篇文章遗留问题的解决方案&#xff0c;导致无法使用 cybertronfurnace 这个工具来完成炼丹&#xff0c;看不到炼丹效果。 但考虑到&#xff0c;以后还是要训练自己的模型&#xff0c; 于是决定放弃 cybertronfurnace&…

数据结构与算法——Java实现 28.二叉树的锯齿形层序遍历

努力成为你想要成为的那种人&#xff0c;去奔赴你想要的生活 —— 24.10.4 103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff…

【Unity】双摄像机叠加渲染

一、前言 之前我在做我的一个Unity项目的时候&#xff0c;需要绘制场景网格的功能&#xff0c;于是就用到了UnityEngine.GL这个图形库来绘制&#xff0c;然后我发现绘制的网格线是渲染在UI之后的&#xff0c;也就是说绘制出来的图形会遮盖在UI上面&#xff0c;也就导致一旦这些…

第十八章(数据在内存中的储存)

1. 整数在内存中的存储 2. ⼤⼩端字节序和字节序判断 3. 浮点数在内存中的存储 我本将心向明月&#xff0c;奈何明月照沟渠正文开始 一、.整数在内存中的储存 整数的2进制的表示方法有三种 1.原码 2.反码 3.补码 这里在第十章我们有详细讲解&#xff0c;有需要的同学可以自…

网络编程项目框架内容

基于TCP的云端书阅管理系统 通过网络实现图书借阅网站&#xff0c;包括服务器与客户端&#xff0c;客户端与服务器是基于TCP连接。 客户端描述&#xff1a;客户端运行会与服务器端进行连接&#xff0c;连接成功后&#xff0c;显示注册登录界面。此时&#xff0c;客户端可以选…

算法: FriendShip - Kruskal+并查集判环

题目 A-Friendship_2024.5.7 (nowcoder.com) 思路分析 求所有符合题意情况的最大值中的最小值&#xff1b;符合题意是指保证图的连通性。那么贪心思路&#xff0c;将所有已存在的关系和可能存在的关系存储起来&#xff0c;利用Kruskal贪心算法每次取权值最小的且不构成回路的…

从零开始讲PCIe(2)——PCI总线传输模型与机制

一、前言 在之前的内容中&#xff0c;我们已经对PCI有了一些基本的认识&#xff0c;我们了解了PCI的一般架构&#xff0c;标准传输周期等相关的内容&#xff0c;接下来我们会进一步了解PCI具体的传输模型和传输机制。 二、PCI传输模型 PCI一共有三种数据传输模型&#xff0c;分…

Windows安装ollama和AnythingLLM

1、Ollama安装部署 1&#xff09;安装ollama 官网下载&#xff1a;https://ollama.com/download&#xff0c;很慢 阿里云盘下载&#xff1a;https://www.alipan.com/s/jiwVVjc7eYb 提取码: ft90 百度云盘下载&#xff1a;https://pan.baidu.com/s/1o1OcY0FkycxMpZ7Ho8_5oA?…

Python-初识Python

前言&#xff1a;在这篇博客当中&#xff0c;我们将步入Python知识的殿堂&#xff0c;Python以其简单、易学、开发效率高在近些年的发展可谓是迅猛&#xff0c;在许多领域都可以见到它的场景&#xff0c;例如&#xff1a;人工智能/机器学习、大数据开发、后端开发等都会用到。 …

仕考网:公务员国考有三不限岗位吗?

国家公务员考试中的“三不限”岗位&#xff0c;即不限制专业背景、政治面貌、基层工作经验的职位。在国考中&#xff0c;是有的但是数量比较少。 这些岗位主要集中在省级及以下单位&#xff0c;以民航空警和铁路公安为主。其中&#xff0c;有一半的职位是面向四项目人员&#…

基于STM32的蓝牙音乐播放器设计

引言 本项目将基于STM32微控制器设计一个简易的蓝牙音乐播放器&#xff0c;通过蓝牙模块接收手机的音乐信号&#xff0c;并使用音频解码芯片播放音乐。该项目展示了STM32在嵌入式音频处理与蓝牙通信方面的应用。 环境准备 1. 硬件设备 STM32F103C8T6 开发板&#xff08;或其…

基于Java,SpringBoot,Vue智慧校园健康驿站体检论坛请假管理系统

摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#xf…

持续更新:当前最好用的AI 编程工具,Cursor 编程指南

本文持续更新&#xff0c;敬请期待更多内容。 文章目录 这一次&#xff0c;AI真懂你的代码关注该关注的&#xff0c;忽略该忽略的1. 创建.cursorignore文件2. 重新索引代码库 参考资料 这一次&#xff0c;AI真懂你的代码 如果你偶尔关注一些AI编程相关的内容&#xff0c;想必你…