开发者学堂课程【全面讲解开源数据库中间件MyCat使用及原理(三):MyCat - 架构剖析 - MyCat 连接池架构实现】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/757/detail/13299
MyCat - 架构剖析 - MyCat 连接池架构实现
内容介绍:
一、连接池创建
二、连接池分配
三、架构
一、连接池创建
连接池是 my cat 的后端连接池,即 my cat 后端与各个数据库节点之间的连接架
MyCat 会根据 dataHost 当中所配置的参数来创建一个连接池,比如代码:
//" maxCon="1000" minCon="10"
这些是创建连接池的参数,minCo 指的就是 connection ,最小连接是10,最大连接是1000。dbType="mysql" dbDriver="native"
决定创建一个什么样的连接池。minCon 根据 schema.xml 文件的配置取得最小的连接数 minCon , 并初始化 mincon 个连接。
在初始化连接时 还需要判定用户选择的是 JDBC 还是原生的 MySQL 协议 以便于创建对应的连接。
二、连接池分配
连接池分配指的是分配连接,即从连接池队列中取出一个连接,在取出一个连接时, Mycat 需要根据负载均衡( balance 属性)的类型选择不同的数据源因为连接和数据源绑在一起,所以需要知道 Mycat 读写的是那些数据源,才能分配响应的连接。
因为在 dataHost 中有代码:
<writeHosthost="hostMl" url="192.168.192.157:3306"user="root"password="itcast">
<readhost host="hostS1" url="192.168.192.158:3306" user="root" password="itcast" /></writehost>
如果配置了读写分离,就需要根据balance来决定当前到底要使用哪一个。
三、架构
MyCatserver 这个就是慢方法当中调用了一个 Startup(),然后就调用了一个 MyCatserver 中的一个 Startup(),在 physicalDBPool 进行初始化一些连接池的相关信息。也可以通过根据跟踪源码按下面这个图的流程简单跟踪一下。
在 MycatStartup 当中调用了 MycatStartup sever 的 startup 方法。
Init datahost 就是在初始化的 dataHost 的部分。
在初始化dataHost的时候,获取到getDataHosts,组装了一个Map<string,PhysicalDBPool >dataHosts=config.getDataHosts();
接下来要初始化 Physica1DBPoo1,调用 init 的方法。接下来点击 init ,代码:
If(!checkIndex(index)) {
Index=0;
}
//进行相应操作
If(initSource(j,writeSources[j]) ) {
//这个代码当中调用了一个方法:init方法,initSource 就是初始化,点击 initSource ,找到代码如下:
Int initSize=ds.getConfig().getMinCon();
//其中 MinCon 获取到的就是参数 minCon="10"
下面的代码:
CopyonWriteArrayList<BackendConnection>list=newCopyOnWriteArrayList<~>();
GetConnectionHandlergetConHandler= new GetConnectionHandler(list, initsize);
// long start =System.currentTimeMillis ();
// long timeout = start + 5000 * 1000L;
//这一部分代码就是创建连接池的过程
代码:ds.getConnection
//调用了 ds,ds 指的就是 physicalDatasource ,获取连接
点击 getConnectio ,在 getConnectio 当中代码:
//当前最大连接
LongactiveCons=increamentCount.longValue()+totalConnectionCount; if (activecons <size){
// 下一个连接大于最大连接数
//在这里进行一个判定,如果下一个连接小于最大连接数,就会创建一个新的连接。
点击 createNewConnection,应用了一个线程池,
代码:
MycatServer.getInstance().getBusinessExecutor()
//通过这个线程池执行了一个任务:创建线程的任务。Mycat 中的线程池在此的作用就是后端用原生协议连接数据。
这个线程池执行的任务:调用 creatNewConnection 这个方法,这是一个抽象方法,作用就是创建新连接。点击时限位的时候,有三个时限:
JDBCDatasource,MYSQLDatasource,PostgreSQLDatasource
, 用哪个时限取决于 dbDriver="native" ,如果选择的是 native ,那么选择的就是 MYSQLDatasource 。如果此处配置的是 JDBC ,说明要使用 JDBCDatasource 连接后端数据库。
点击 MYSQLDatasource ,此处调用了 factory.make ,作用是执行创建连接的过程。
make方法最终返回了 MYSQLConnection ,这就是创建了后端连接。
接下来应用了一个代码:
MysQLConnection c = new MySQLConnection(channel, pool.isReadNode ());
紧接着设置了一系列的参数,然后进行了一个if条件判断,主要是判断当前的 io 模型是 aio 还是 nio ,
代码如下:
If (channel instanceof AsynchronousSocketChannel){
((AsynchronousSocketChannel) channel).connect (
new InetSocketAddress (dsc.getIp(), dsc.getPort()), c,
(CompletionHandler) MycatServer.getInstance()
.getConnector());
//如果 channel 是一个 aio ,则创建的是一个 aio
}else {
((NIOConnector) MycatServergetInstance().getConnector())
.postConnect(c);
//如果不是 aio ,则是 nio ,创建一个 nio 。
最终将 MySQLConnection 返回,通过这个 MySQLConnection 连接后端的 MYSQL Database 。