186-6908-0178
当前位置:首页 >程序开发
【MYSQL】MYSQL学习的一大重点:MySQL连接池原理与分析简易网站数据流动是如何进行
2026-09-10 1次浏览

1 ~> MySQL 连接池原理与实现

1.1 连接池产生背景:短连接的性能瓶颈

传统数据库短连接模式下,每次执行 SQL 都会执行完整的生命周期 :


创建 MySQL 句柄对象

发起 TCP 连接、完成 MySQL 身份认证

执行 SQL 语句、处理结果

关闭连接、释放资源

核心弊端:


频繁的 TCP 三次握手、四次挥手带来巨大网络开销

MySQL 连接的身份认证、权限校验属于重操作,重复执行严重浪费 CPU 资源

高并发场景下,大量连接的创建与销毁会导致数据库连接数溢出,引发服务雪崩

1.2 连接池核心设计思想

核心本质:空间换时间,预先创建一批数据库连接并长期保持活跃,业务请求直接复用已有连接,避免重复建连开销。

核心价值:

消除连接建立与销毁的开销,大幅降低 SQL 执行延迟

统一管控连接数量,避免数据库连接数超出上限

统一封装数据库操作,业务层无需关心连接底层细节

1.3 线程绑定式连接池实现模型

该模型是 C/C++ 生态最常用的连接池实现方案,核心逻辑为一个工作线程绑定一个数据库连接,基于线程池实现任务调度。


1.3.1 核心组件

任务队列:全局共享的阻塞队列,存储待执行的 SQL 任务

任务结构体包含两个核心字段:SQL 语句、回调函数对象

多线程环境下通过互斥锁保证队列操作线程安全,通过条件变量实现任务等待与唤醒

工作线程池:预先创建的 N 个工作线程

每个线程启动阶段就完成 MySQL 连接建立,线程生命周期内持有该连接句柄

线程进入事件主循环:阻塞等待任务队列,取出任务后通过自身持有的连接执行 SQL

连接句柄:每个线程独立持有一个MYSQL*对象,全程绑定,不跨线程传递。

关键约束:MySQL 连接句柄不是线程安全的,绝对禁止多线程共享同一个连接句柄并发执行 SQL,这也是 “一线程一连接” 设计的核心依据。

1.3.2 任务执行与回调机制

任务提交:业务层将 SQL 语句与回调函数封装为任务对象,推入任务队列

任务执行:工作线程取出任务,调用mysql_query接口执行 SQL 语句

结果回调:

增删改类 SQL:若无回调则直接结束;有回调则将执行状态码传入回调函数

查询类 SQL:执行后通过mysql_store_result获取结果集,将结果集传入回调函数,由业务层处理数据

设计意义:实现异步数据库操作,业务层提交任务后无需阻塞等待,结果通过回调函数异步返回。

1.3.3 连接保活与故障恢复

问题:MySQL 连接可能因网络波动、服务端超时等原因断开,直接执行 SQL 会报错

标准解决方案:

执行 SQL 前调用mysql_ping()检测连接有效性

若连接已断开,调用mysql_real_connect重新建立连接

也可通过mysql_options设置MYSQL_OPT_RECONNECT选项,开启客户端自动重连能力

1.3.4 单连接基础 API 示例

以下为 C++ 调用 MySQL C API 的基础连接实现,是连接池单线程的核心逻辑原型:


#include <iostream>

#include <string>

#include <mysql/mysql.h>


// 数据库连接配置

const std::string host = "localhost";    // 修正原笔记拼写错误

const std::string user = "connector";

const std::string passwd = "123456";

const std::string db = "conn";

const unsigned int port = 3306;          // 修正原笔记端口错误,MySQL默认端口3306


int main() {

    // 1. 初始化MySQL句柄

    MYSQL* my = mysql_init(nullptr);

    if (nullptr == my) {

        std::cerr << "init MySQL error" << std::endl;

        return 1;

    }


    // 2. 建立数据库连接(线程启动阶段执行一次)

    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(),

                           db.c_str(), port, nullptr, 0) == nullptr) {

        std::cerr << "connect MySQL error: " << mysql_error(my) << std::endl;

        return 2;

    }


    // 3. 设置连接字符集

    mysql_set_character_set(my, "utf8");


    // 4. 执行SQL语句(事件循环中,每次取出任务后执行)

    // 增删改操作示例

    // std::string sql = "insert into user (name, age, telephone) values('张', 19, '6543219')";

    // std::string sql = "update user set name='Jimmy' where id=2";

    // std::string sql = "delete from user where id=5";


    // 查询操作示例

    std::string sql = "select * from user";


    int ret = mysql_query(my, sql.c_str());

    if (ret == 0) {

        std::cout << sql << " execute success" << std::endl;


        // 查询类SQL需要获取结果集,回调函数通常在此处触发

        MYSQL_RES* res = mysql_store_result(my);

        if (res) {

            MYSQL_ROW row;

            // 遍历结果集,将数据传入回调函数

            while ((row = mysql_fetch_row(res)) != nullptr) {

                std::cout << "id: " << row[0] << ", name: " << row[1] << std::endl;

            }

            mysql_free_result(res);

        }

    } else {

        std::cerr << sql << " execute failed: " << mysql_error(my) << std::endl;

        return 3;

    }


    // 连接池场景下连接不关闭,线程生命周期结束时再释放

    mysql_close(my);

    return 0;

}

看看AI怎么写

cpp

运行

#include <iostream>

#include <string>

#include <mysql/mysql.h>


// 数据库连接配置

const std::string host = "localhost";    // 修正原笔记拼写错误

const std::string user = "connector";

const std::string passwd = "123456";

const std::string db = "conn";

const unsigned int port = 3306;          // 修正原笔记端口错误,MySQL默认端口3306


int main() {

    // 1. 初始化MySQL句柄

    MYSQL* my = mysql_init(nullptr);

    if (nullptr == my) {

        std::cerr << "init MySQL error" << std::endl;

        return 1;

    }


    // 2. 建立数据库连接(线程启动阶段执行一次)

    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(),

                           db.c_str(), port, nullptr, 0) == nullptr) {

        std::cerr << "connect MySQL error: " << mysql_error(my) << std::endl;

        return 2;

    }


    // 3. 设置连接字符集

    mysql_set_character_set(my, "utf8");


    // 4. 执行SQL语句(事件循环中,每次取出任务后执行)

    // 增删改操作示例

    // std::string sql = "insert into user (name, age, telephone) values('张', 19, '6543219')";

    // std::string sql = "update user set name='Jimmy' where id=2";

    // std::string sql = "delete from user where id=5";


    // 查询操作示例

    std::string sql = "select * from user";


    int ret = mysql_query(my, sql.c_str());

    if (ret == 0) {

        std::cout << sql << " execute success" << std::endl;


        // 查询类SQL需要获取结果集,回调函数通常在此处触发

        MYSQL_RES* res = mysql_store_result(my);

        if (res) {

            MYSQL_ROW row;

            // 遍历结果集,将数据传入回调函数

            while ((row = mysql_fetch_row(res)) != nullptr) {

                std::cout << "id: " << row[0] << ", name: " << row[1] << std::endl;

            }

            mysql_free_result(res);

        }

    } else {

        std::cerr << sql << " execute failed: " << mysql_error(my) << std::endl;

        return 3;

    }


    // 连接池场景下连接不关闭,线程生命周期结束时再释放

    mysql_close(my);

    return 0;

}

1.4 完整 C++ MySQL 连接池工程实现

1.4.1 核心设计约束

线程与连接一一绑定,连接生命周期与线程生命周期完全一致,符合 MySQL 连接非线程安全的底层约束

基于生产者 - 消费者模型,通过互斥锁 + 条件变量实现任务队列的线程安全调度

内置连接保活机制,自动检测连接状态并完成重连,提升服务可用性

基于std::function实现通用回调接口,支持任意业务层的结果处理逻辑

RAII 资源管理,析构时自动停止线程、释放所有数据库连接,无内存与连接泄漏

1.4.2 完整可运行代码

#include <iostream>

#include <string>

#include <vector>

#include <queue>

#include <thread>

#include <mutex>

#include <condition_variable>

#include <functional>

#include <atomic>

#include <chrono>

#include <mysql/mysql.h>


// 数据库任务结构体:封装SQL语句与结果回调

struct SqlTask {

    std::string sql;

    // 回调函数签名:参数1为执行结果码(0成功,非0失败),参数2为查询结果集(仅查询类SQL有效)

    std::function<void(int, MYSQL_RES*)> callback;

};


// MySQL连接池类:线程绑定式实现

class MysqlConnectionPool {

public:

    /**

     * @brief 构造函数

     * @param pool_size 连接池大小(工作线程数 = 数据库连接数)

     * @param host 数据库主机地址

     * @param user 数据库用户名

     * @param passwd 数据库密码

     * @param db 目标数据库名

     * @param port 数据库端口

     */

    MysqlConnectionPool(size_t pool_size, 

                        const std::string& host,

                        const std::string& user,

                        const std::string& passwd,

                        const std::string& db,

                        unsigned int port);


    // 析构函数:停止线程池,释放所有数据库连接

    ~MysqlConnectionPool();


    // 禁止拷贝构造与赋值(资源类禁止拷贝)

    MysqlConnectionPool(const MysqlConnectionPool&) = delete;

    MysqlConnectionPool& operator=(const MysqlConnectionPool&) = delete;


    /**

     * @brief 向连接池提交SQL任务(生产者接口)

     * @param task 待执行的SQL任务

     */

    void pushTask(const SqlTask& task);


private:

    /**

     * @brief 工作线程入口函数(消费者逻辑)

     * 每个线程独立创建并持有一个MySQL连接,全程绑定

     */

    void workerThread(const std::string& host,

                      const std::string& user,

                      const std::string& passwd,

                      const std::string& db,

                      unsigned int port);


    /**

     * @brief 连接保活检测与自动重连

     * @param mysql 待检测的MySQL连接句柄

     * @return true 连接可用;false 连接失效且重连失败

     */

    bool ensureConnected(MYSQL* mysql);


private:

    std::vector<std::thread> m_workers;    // 工作线程池

    std::queue<SqlTask> m_taskQueue;       // 全局任务队列

    std::mutex m_queueMutex;               // 任务队列互斥锁

    std::condition_variable m_cond;        // 任务唤醒条件变量

    std::atomic<bool> m_isStop;            // 线程池停止标志(原子变量保证线程可见)

};


// ===================== 类成员函数实现 =====================


MysqlConnectionPool::MysqlConnectionPool(size_t pool_size,

                                         const std::string& host,

                                         const std::string& user,

                                         const std::string& passwd,

                                         const std::string& db,

                                         unsigned int port)

    : m_isStop(false) {

    // 批量创建工作线程,每个线程独立完成MySQL连接初始化

    for (size_t i = 0; i < pool_size; ++i) {

        m_workers.emplace_back(&MysqlConnectionPool::workerThread, this,

                               host, user, passwd, db, port);

    }

}


MysqlConnectionPool::~MysqlConnectionPool() {

    // 1. 设置停止标志,通知所有线程退出循环

    m_isStop.store(true);

    // 2. 唤醒所有阻塞在条件变量上的线程

    m_cond.notify_all();


    // 3. 等待所有线程安全退出,回收资源

    for (auto& th : m_workers) {

        if (th.joinable()) {

            th.join();

        }

    }

}


void MysqlConnectionPool::pushTask(const SqlTask& task) {

    {

        std::lock_guard<std::mutex> lock(m_queueMutex);

        m_taskQueue.push(task);

    }

    // 任务入队后,唤醒一个工作线程处理

    m_cond.notify_one();

}


bool MysqlConnectionPool::ensureConnected(MYSQL* mysql) {

    if (mysql == nullptr) {

        return false;

    }

    // mysql_ping返回0表示连接存活,非0表示连接已断开

    if (mysql_ping(mysql) != 0) {

        std::cerr << "[Warning] MySQL connection lost, try reconnect..." << std::endl;

        // 连接断开,执行重连

        if (mysql_real_connect(mysql, nullptr, nullptr, nullptr, nullptr, 0, nullptr, 0) == nullptr) {

            std::cerr << "[Error] MySQL reconnect failed: " << mysql_error(mysql) << std::endl;

            return false;

        }

        // 重连后重置字符集

        mysql_set_character_set(mysql, "utf8");

    }

    return true;

}


void MysqlConnectionPool::workerThread(const std::string& host,

                                       const std::string& user,

                                       const std::string& passwd,

                                       const std::string& db,

                                       unsigned int port) {

    // ========== 线程初始化阶段:创建并建立数据库连接 ==========

    MYSQL* mysql = mysql_init(nullptr);

    if (mysql == nullptr) {

        std::cerr << "[Error] mysql_init failed in worker thread" << std::endl;

        return;

    }


    if (mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(),

                           db.c_str(), port, nullptr, 0) == nullptr) {

        std::cerr << "[Error] worker thread connect MySQL failed: " 

                  << mysql_error(mysql) << std::endl;

        mysql_close(mysql);

        return;

    }

    mysql_set_character_set(mysql, "utf8");


    // ========== 线程主循环:阻塞取任务 -> 执行SQL -> 回调通知 ==========

    while (!m_isStop.load()) {

        SqlTask task;

        {

            std::unique_lock<std::mutex> lock(m_queueMutex);

            // 条件变量等待,谓词判断防止虚假唤醒

            m_cond.wait(lock, [this]() {

                return !m_taskQueue.empty() || m_isStop.load();

            });


            // 停止标志触发且无剩余任务时,退出主循环

            if (m_isStop.load() && m_taskQueue.empty()) {

                break;

            }


            // 取出队首任务

            task = std::move(m_taskQueue.front());

            m_taskQueue.pop();

        }


        // 执行SQL前先做连接保活检测

        if (!ensureConnected(mysql)) {

            // 连接不可用,通过回调通知业务层错误

            if (task.callback) {

                task.callback(-1, nullptr);

            }

            continue;

        }


        // 执行SQL语句

        int ret = mysql_query(mysql, task.sql.c_str());

        if (ret != 0) {

            std::cerr << "[Error] sql execute failed: " << task.sql 

                      << ", reason: " << mysql_error(mysql) << std::endl;

            if (task.callback) {

                task.callback(ret, nullptr);

            }

            continue;

        }


        // SQL执行成功,获取结果集

        MYSQL_RES* res = mysql_store_result(mysql);

        

        // 执行回调,将结果交付给业务层

        if (task.callback) {

            task.callback(0, res);

        }


        // 释放结果集资源(必须释放,否则造成内存泄漏)

        if (res) {

            mysql_free_result(res);

        }

    }


    // ========== 线程退出阶段:关闭数据库连接 ==========

    mysql_close(mysql);

}


// ===================== 使用示例 =====================

int main() {

    // 1. 初始化连接池,设置4个连接(4个工作线程)

    MysqlConnectionPool pool(4, "localhost", "connector", "123456", "conn", 3306);


    // 2. 提交写入任务(无回调,异步执行)

    SqlTask insert_task;

    insert_task.sql = "insert into user (name, age, telephone) values('pool_test', 22, '987654321')";

    pool.pushTask(insert_task);


    // 3. 提交查询任务(带回调,异步接收结果)

    SqlTask select_task;

    select_task.sql = "select id, name, age from user";

    select_task.callback = [](int ret, MYSQL_RES* res) {

        if (ret != 0 || res == nullptr) {

            std::cout << "query execute failed" << std::endl;

            return;

        }

        // 业务层遍历处理结果集

        MYSQL_ROW row;

        std::cout << "===== query result =====" << std::endl;

        while ((row = mysql_fetch_row(res)) != nullptr) {

            std::cout << "id: " << row[0] 

                      << ", name: " << row[1] 

                      << ", age: " << row[2] << std::endl;

        }

    };

    pool.pushTask(select_task);


    // 演示等待:实际工程中无需此操作,此处保证任务执行完成

    std::this_thread::sleep_for(std::chrono::seconds(2));


    return 0;

}

看看AI怎么写

cpp

运行

#include <iostream>

#include <string>

#include <vector>

#include <queue>

#include <thread>

#include <mutex>

#include <condition_variable>

#include <functional>

#include <atomic>

#include <chrono>

#include <mysql/mysql.h>


// 数据库任务结构体:封装SQL语句与结果回调

struct SqlTask {

    std::string sql;

    // 回调函数签名:参数1为执行结果码(0成功,非0失败),参数2为查询结果集(仅查询类SQL有效)

    std::function<void(int, MYSQL_RES*)> callback;

};


// MySQL连接池类:线程绑定式实现

class MysqlConnectionPool {

public:

    /**

     * @brief 构造函数

     * @param pool_size 连接池大小(工作线程数 = 数据库连接数)

     * @param host 数据库主机地址

     * @param user 数据库用户名

     * @param passwd 数据库密码

     * @param db 目标数据库名

     * @param port 数据库端口

     */

    MysqlConnectionPool(size_t pool_size, 

                        const std::string& host,

                        const std::string& user,

                        const std::string& passwd,

                        const std::string& db,

                        unsigned int port);


    // 析构函数:停止线程池,释放所有数据库连接

    ~MysqlConnectionPool();


    // 禁止拷贝构造与赋值(资源类禁止拷贝)

    MysqlConnectionPool(const MysqlConnectionPool&) = delete;

    MysqlConnectionPool& operator=(const MysqlConnectionPool&) = delete;


    /**

     * @brief 向连接池提交SQL任务(生产者接口)

     * @param task 待执行的SQL任务

     */

    void pushTask(const SqlTask& task);


private:

    /**

     * @brief 工作线程入口函数(消费者逻辑)

     * 每个线程独立创建并持有一个MySQL连接,全程绑定

     */

    void workerThread(const std::string& host,

                      const std::string& user,

                      const std::string& passwd,

                      const std::string& db,

                      unsigned int port);


    /**

     * @brief 连接保活检测与自动重连

     * @param mysql 待检测的MySQL连接句柄

     * @return true 连接可用;false 连接失效且重连失败

     */

    bool ensureConnected(MYSQL* mysql);


private:

    std::vector<std::thread> m_workers;    // 工作线程池

    std::queue<SqlTask> m_taskQueue;       // 全局任务队列

    std::mutex m_queueMutex;               // 任务队列互斥锁

    std::condition_variable m_cond;        // 任务唤醒条件变量

    std::atomic<bool> m_isStop;            // 线程池停止标志(原子变量保证线程可见)

};


// ===================== 类成员函数实现 =====================


MysqlConnectionPool::MysqlConnectionPool(size_t pool_size,

                                         const std::string& host,

                                         const std::string& user,

                                         const std::string& passwd,

                                         const std::string& db,

                                         unsigned int port)

    : m_isStop(false) {

    // 批量创建工作线程,每个线程独立完成MySQL连接初始化

    for (size_t i = 0; i < pool_size; ++i) {

        m_workers.emplace_back(&MysqlConnectionPool::workerThread, this,

                               host, user, passwd, db, port);

    }

}


MysqlConnectionPool::~MysqlConnectionPool() {

    // 1. 设置停止标志,通知所有线程退出循环

    m_isStop.store(true);

    // 2. 唤醒所有阻塞在条件变量上的线程

    m_cond.notify_all();


    // 3. 等待所有线程安全退出,回收资源

    for (auto& th : m_workers) {

        if (th.joinable()) {

            th.join();

        }

    }

}


void MysqlConnectionPool::pushTask(const SqlTask& task) {

    {

        std::lock_guard<std::mutex> lock(m_queueMutex);

        m_taskQueue.push(task);

    }

    // 任务入队后,唤醒一个工作线程处理

    m_cond.notify_one();

}


bool MysqlConnectionPool::ensureConnected(MYSQL* mysql) {

    if (mysql == nullptr) {

        return false;

    }

    // mysql_ping返回0表示连接存活,非0表示连接已断开

    if (mysql_ping(mysql) != 0) {

        std::cerr << "[Warning] MySQL connection lost, try reconnect..." << std::endl;

        // 连接断开,执行重连

        if (mysql_real_connect(mysql, nullptr, nullptr, nullptr, nullptr, 0, nullptr, 0) == nullptr) {

            std::cerr << "[Error] MySQL reconnect failed: " << mysql_error(mysql) << std::endl;

            return false;

        }

        // 重连后重置字符集

        mysql_set_character_set(mysql, "utf8");

    }

    return true;

}


void MysqlConnectionPool::workerThread(const std::string& host,

                                       const std::string& user,

                                       const std::string& passwd,

                                       const std::string& db,

                                       unsigned int port) {

    // ========== 线程初始化阶段:创建并建立数据库连接 ==========

    MYSQL* mysql = mysql_init(nullptr);

    if (mysql == nullptr) {

        std::cerr << "[Error] mysql_init failed in worker thread" << std::endl;

        return;

    }


    if (mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(),

                           db.c_str(), port, nullptr, 0) == nullptr) {

        std::cerr << "[Error] worker thread connect MySQL failed: " 

                  << mysql_error(mysql) << std::endl;

        mysql_close(mysql);

        return;

    }

    mysql_set_character_set(mysql, "utf8");


    // ========== 线程主循环:阻塞取任务 -> 执行SQL -> 回调通知 ==========

    while (!m_isStop.load()) {

        SqlTask task;

        {

            std::unique_lock<std::mutex> lock(m_queueMutex);

            // 条件变量等待,谓词判断防止虚假唤醒

            m_cond.wait(lock, [this]() {

                return !m_taskQueue.empty() || m_isStop.load();

            });


            // 停止标志触发且无剩余任务时,退出主循环

            if (m_isStop.load() && m_taskQueue.empty()) {

                break;

            }


            // 取出队首任务

            task = std::move(m_taskQueue.front());

            m_taskQueue.pop();

        }


        // 执行SQL前先做连接保活检测

        if (!ensureConnected(mysql)) {

            // 连接不可用,通过回调通知业务层错误

            if (task.callback) {

                task.callback(-1, nullptr);

            }

            continue;

        }


        // 执行SQL语句

        int ret = mysql_query(mysql, task.sql.c_str());

        if (ret != 0) {

            std::cerr << "[Error] sql execute failed: " << task.sql 

                      << ", reason: " << mysql_error(mysql) << std::endl;

            if (task.callback) {

                task.callback(ret, nullptr);

            }

            continue;

        }


        // SQL执行成功,获取结果集

        MYSQL_RES* res = mysql_store_result(mysql);

        

        // 执行回调,将结果交付给业务层

        if (task.callback) {

            task.callback(0, res);

        }


        // 释放结果集资源(必须释放,否则造成内存泄漏)

        if (res) {

            mysql_free_result(res);

        }

    }


    // ========== 线程退出阶段:关闭数据库连接 ==========

    mysql_close(mysql);

}


// ===================== 使用示例 =====================

int main() {

    // 1. 初始化连接池,设置4个连接(4个工作线程)

    MysqlConnectionPool pool(4, "localhost", "connector", "123456", "conn", 3306);


    // 2. 提交写入任务(无回调,异步执行)

    SqlTask insert_task;

    insert_task.sql = "insert into user (name, age, telephone) values('pool_test', 22, '987654321')";

    pool.pushTask(insert_task);


    // 3. 提交查询任务(带回调,异步接收结果)

    SqlTask select_task;

    select_task.sql = "select id, name, age from user";

    select_task.callback = [](int ret, MYSQL_RES* res) {

        if (ret != 0 || res == nullptr) {

            std::cout << "query execute failed" << std::endl;

            return;

        }

        // 业务层遍历处理结果集

        MYSQL_ROW row;

        std::cout << "===== query result =====" << std::endl;

        while ((row = mysql_fetch_row(res)) != nullptr) {

            std::cout << "id: " << row[0] 

                      << ", name: " << row[1] 

                      << ", age: " << row[2] << std::endl;

        }

    };

    pool.pushTask(select_task);


    // 演示等待:实际工程中无需此操作,此处保证任务执行完成

    std::this_thread::sleep_for(std::chrono::seconds(2));


    return 0;

}

1.5 业界主流连接池组件

Java 生态:HikariCP(目前性能最优的 JDBC 连接池)、Druid(带监控与防火墙能力)、C3P0

C/C++ 生态:多为业务自研实现,也可基于 MySQL Connector/C++、libzdb 等开源库二次封装

2 ~> 网站数据流动与分布式架构演进

2.1 基础 Web 业务全链路(注册 / 登录场景)

2.1.1 用户注册全链路

客户端发起 HTTP 请求,访问网站注册页面

Web 服务器(Nginx/Tomcat)接收请求,返回前端注册页面

用户填写用户名、密码、手机号等信息,通过 POST 方法提交表单数据

后端服务(PHP/Python/Java/C++)提取表单参数,完成合法性校验

后端构建 INSERT SQL 语句,调用数据库连接池执行写入操作

用户数据持久化到 MySQL 用户表,注册流程完成

2.1.2 用户登录全链路

客户端发起 HTTP 请求,访问网站登录页面

Web 服务器返回登录页面

用户输入用户名、密码,通过 POST 方法提交(禁止 GET 提交密码,防止明文泄露)

后端提取参数,构建 SELECT 查询 SQL,查询条件为用户名 + 密码

连接池执行 SQL,从数据库查询匹配记录

若查询到记录,说明用户身份合法,后端生成 Cookie/Session 信息返回客户端,登录成功

若无匹配记录,返回账号或密码错误提示

2.2 数据库层架构演进

2.2.1 单库架构

小型网站初期形态:所有读写操作都访问同一台 MySQL 服务器

弊端:存在单点故障风险、性能上限低,无法支撑高并发读写场景

2.2.2 主从复制与读写分离

核心架构:一主多从,主库(Master)负责所有写操作,从库(Slave)负责读操作

数据同步:主库通过 binlog 日志将数据变更同步到所有从库,保证数据最终一致性

核心优势:

读写分流,大幅提升数据库并发处理能力

从库可做冷备,降低数据丢失风险

2.2.3 数据库中间件 与负载均衡

引入原因:业务层直接对接多台数据库会导致耦合度高,无法统一管控

中间件核心作用:

对业务层屏蔽后端数据库集群细节,业务层只需对接中间件

实现 SQL 路由、读写分离、读请求负载均衡

统一管控连接数、权限控制、SQL 监控与审计

常见中间件:ShardingSphere、MyCat、ProxySQL

2.3 缓存层设计

引入背景:高频热点数据每次都查询数据库,会给数据库造成巨大压力

核心思想:查询请求优先访问缓存,缓存命中直接返回;缓存未命中再查询数据库,同时将数据回写缓存

主流缓存组件:Redis(分布式缓存首选)、Memcached

2.4 大规模分布式架构核心组件

随着业务规模扩大,架构会逐步引入更多分布式组件:


容器化与编排:Docker(应用容器化)、Kubernetes(K8S,容器集群编排)

消息队列:Kafka、RabbitMQ,用于异步解耦、流量削峰

分布式存储:应对海量数据存储需求

微服务治理:服务注册发现、熔断降级、全链路追踪

技术栈定位补充


Java:建站效率高、生态完善,是互联网业务后端的主流选择

C/C++:性能优势明显,常用于高性能中间件、底层基础组件开发

PHP/Python:适合小型项目、快速迭代的业务场景


————————————————

版权声明:本文为CSDN博主「艾莉丝努力练剑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/2401_89899187/article/details/163252580


回到顶部