本文主要是介绍笔记-连接池,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
笔记-连接池
池化技术
池化技术能够减少资源对象的创建次数, 减少对象创建和销毁的事件
原理
- 正常一个MySQL的操作流程: TCP三次握手->MySQL认证->SQL执行->MySQL关闭->四次挥手
- 将TCP三次握手和MySQL认证创建后的连接放到连接容器(连接池)中
- 池化后的MySQL操作流程: 从连接池取出一个连接->MySQL执行->归还MySQL连接
连接池设计
- DBConnection, 数据库的连接对象, 同时数据库的操作由DBConnection实现
- DBConnectionPool, 数据库连接对象的池化管理类, 主要是对DBConnection的管理
- m_free_list, 空闲的连接, 通过链表管理
- m_used_list, 被使用的连接, 通过链表管理
- int m_max_conn_cnt, 线程池最大容纳连接数
- int m_cur_conn_cnt, 当前创建的连接数
- m_abort_request, 退出连接池
- std::mutex m_mutex, 互斥量
- std::condition_variable m_cond, 通知陷入超时等待getDBConnect函数可以取连接对象
- int init(), 创建m_cur_conn_cnt大小的连接数, m_cur_conn_cnt需要在构造函数中赋值最小连接数
- DBConnection* getDBConnection(const int timeout_ms), 获取连接
- 空闲队列为空, 当前连接大于等于最大连接, timeout不大于0, m_cond.wait()
- 空闲队列为空, 当前连接大于等于最大连接, timeout大于0, m_cond.wait_for()
- 空闲队列为空, 当前连接小于最大连接, 创建新的连接, 添加到空闲队列中
- 从空闲队列中取除连接, 然后将连接放到m_used_list中
- void relDbConnection(DBConnection* conn), 归还连接, 用完连接之后必须归还
- 将conn从m_used_list中删除
- 将conn添加到m_free_list中
- 通过m_cond.notufy_one()通知陷入m_cond.wait()的线程
- ~DBConnectionPool
- 将m_abort_request=true
- 利用m_cond.notify_all()通知所有等待超时的线程
- 删除m_free_conn;
MySQL连接重连机制
- 方法
- 每次操作之前先去测试链路是否通
- 先执行任务
- 执行失败后mysql_ping
- 执行失败后释放资源, mysql_close(mysql); mysql = NULL;, 这样情况下需要对free_conn_list中的conn进行if=NULL判断
- 设置启用(当发现连接断开时的)自动重连
my_bool reconnect = true;
mysql_options(m_mysql, MYSQL_OPT_RECONNECT, &reconnect); // 配合mysql_ping实现自动重连 - 检测连接是否正常
int STDCALL mysql_ping(MYSQL *mysql);
检查与服务端的连接是否正常。连接断开时,如果自动重新连接功能未被禁用,则尝试重新连接服务器。该函数可被客户端用来检测闲置许久以后,与服务端的连接是否关闭,如有需要,则重新连接。
返回值:
连接正常,返回0;如有错误发生,则返回非0值。返回非0值并不意味着服务器本身关闭掉,也有可能是网络原因导致网络不通. - 每一次执行MySQL语句都先用mysql_ping进行检测
其他
- 线程池和连接池有什么区别? 线程池, 主动操作, 主动去执行任务; 连接池, 被动操作, 池的对象被任务获取, 执行完任务后归还.
- 每个线程绑定一个连接的方法缺点? 代码耦合性高
- 长连接和短连接的区别? 连接池使用的是长连接.
- 同步连接和异步连接? 同步连接池,存在IO阻塞; 异步连接池, 效率高, 但会增加编程难度.
这篇关于笔记-连接池的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!