网络上有关于DruidDataSource的资料很多,但是关于HighAvailableDataSource的介绍就少了很多,应该是这种场景确实使用的不多。
笔者所在公司使用了Mycat(基于此进行二次魔改),Mycat集群提供分库分表的能力,对于客户端而言,连接Mycat集群,就是使用的HighAvailableDataSource来完成的。
本文就来简单介绍下HighAvailableDataSource的三种使用方式。
HighAvailableDataSource本质上是对多种数据源的一个封装,使用特定的选择器(selector)来完成数据源的使用。
1.直接定义的方式直接定义就是将HighAvailableDataSource所需要的DataSource全部手动添加到HighAvailableDataSource.dataSourceMap中
1.1 API // 创建DataSource1
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/datasource1");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.init();
// 创建DataSource2
DruidDataSource dataSource2 = new DruidDataSource();
dataSource2.setUrl("jdbc:mysql://localhost:3306/datasource2");
dataSource2.setUsername("root");
dataSource2.setPassword("root");
dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
dataSource2.init();
// 创建HighAvailableDataSource
HighAvailableDataSource haDataSource = new HighAvailableDataSource();
// 将上述创建的两个DataSource添加到haDatasource中
Map dataSourceMap = new ConcurrentHashMap();
dataSourceMap.put("datasource1", dataSource);
dataSourceMap.put("datasource2", dataSource2);
haDataSource.setDataSourceMap(dataSourceMap);
haDataSource.init();
// 获取连接
Connection connection = haDataSource.getConnection();
直接使用API的方式来创建非常简单,就是创建两个DataSource之后,将这两个DataSource添加到HighAvailableDataSource.dataSourceMap即可,就完成了HighAvailableDataSource的封装。
HighAvailableDataSource的选择器默认为random,在真正获取Connection时,会使用随机的方式选择这两个DataSource之一来创建连接。
1.2 XML
所表达的含义与上述API代码是一致的,不再赘述。
2.使用file的方式HighAvailableDataSource提供file的方式来提供多数据源信息,如下所示:
创建文件ha-datasource.properties(注意目录)
ha.datasource1.url=jdbc:mysql://localhost:3306/datasource1
ha.datasource1.username=root
ha.datasource1.password=root
ha.datasource2.url=jdbc:mysql://localhost:3306/datasource2
ha.datasource2.username=root
ha.datasource2.password=root
2.1 API
// 创建HighAvailableDataSource
HighAvailableDataSource haDataSource = new HighAvailableDataSource();
// 设置文件路径
haDataSource.setDataSourceFile("ha-datasource.properties");
// 设置前缀,这个需要与配置文件中的前缀保持一致
haDataSource.setPropertyPrefix("ha");
haDataSource.init();
// 获取连接
Connection connection = haDataSource.getConnection();
我们在ha-datasource.properties中定义的前缀为ha,所以在创建HighAvailableDataSource时,我们设置propertyPrefix属性为ha
2.2 XML方式
3.Zookeeper方式
HighAvailableDataSource还提供了Zookeeper的方式来动态获取数据源信息。另外使用Zookeeper还有一个好处,就是当节点发生变更时可以及时反映到HighAvailableDataSource中(比较适合动态扩缩容DataSource)
首先我们需要创建好zk节点信息,笔者创建如下:
其中127.0.0.1代表一个DataSource所在的地址,具体值为:
ha.database=datasource1
ha.host=127.0.0.1
ha.username=root
ha.password=root
ha.port=3306
127.0.0.2节点的值为:
ha.database=datasource2
ha.host=127.0.0.2
ha.username=root
ha.password=root
ha.port=3306
创建完成这些节点之后,我们再来创建HighAvailableDataSource
3.1 API // 创建Listener
ZookeeperNodeListener listener = new ZookeeperNodeListener();
// 这里是zk的地址
listener.setZkConnectString("localhost:2181");
// 这里的前缀就是上面两个节点中的前缀信息
listener.setPrefix("ha");
// 这里的path就是两个节点的父目录
listener.setPath("/ha-druid-datasources/hatest");
// 提供一个url模板,后续会通过读取节点值信息将该模板拼装好
listener.setUrlTemplate("jdbc:mysql://#host#:#port#/#database#");
// 创建HighAvailableDataSource
HighAvailableDataSource haDataSource = new HighAvailableDataSource();
haDataSource.setNodeListener(listener);
haDataSource.init();
// 获取连接
Connection connection = haDataSource.getConnection();
这里使用ZookeeperNodeListener,我们需要注意的就是,prefix和path、urlTemplate三个属性的填写,按照这种标准格式填写,最终会将两个节点的信息拼装到urlTemplate中,最终拼接为:jdbc:mysql://127.0.0.1:3306/datasource1、jdbc:mysql://127.0.0.2:3306/datasource2
3.2 XML
总结:
有关于HighAvailableDataSource的源码还是比较简单的,笔者就不再深入分析。
日常如果有多数据源(轮询使用)的使用这种场景,我们可以考虑使用以上三种方式的任一种来创建。