背景
使用jdbc连接GBASE 8a数据库时,当连接全都集中在同一个coor节点时,降低集群coor节点的利用率。其实GBASE8a JDBC实现了负载均衡的功能。
其实现原理为轮询,需要配置三个参数:
failoverEnable=true
hostList=192.168.198.112,192.168.198.113
gclusterId=gcl1
为了验证其是否实现了负载均衡,经过简单的反射可以查看其真实连接的IP地址,代码如下:
import com.gbase.jdbc.ConnectionImpl;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
public class Test {
public static void main(String[] args) throws Exception {
Test test = new Test();
test.test2();
}
public void test2() throws Exception {
String url = "jdbc:gbase://192.168.198.111:5258/gbase?" +
"user=gbase&" +
"password=gbase20110531&" +
"failoverEnable=true&" +
"hostList=192.168.198.112,192.168.198.113&" +
"gclusterId=gcl1";
Connection conn = null;
for (int i = 0; i < 1000; i++) {
conn = DriverManager.getConnection(url);
if (conn != null) {
//反射拆解对象
Class<ConnectionImpl> clazz = ConnectionImpl.class;
Field host = clazz.getDeclaredField("host");
host.setAccessible(true);
Object serverIP = host.get(conn);
System.out.println(serverIP);
conn.close();
}
}
}
}
结果
可见其确实实现了节点间的飘移。
一些骚操作
在一些场景中,机器的性能可能会有差异,虽然不需要精确的量化,但是可能会有需求的减少某台机器的负载,虽然jdbc的机制是轮询,或许我们可以通过url的配置实现我们想要的功能,比如将其他的机器ip多配置几次。
如果这样配置url
String url = "jdbc:gbase://192.168.198.111:5258/gbase?" +
"user=gbase&" +
"password=gbase20110531&" +
"failoverEnable=true&" +
"hostList=192.168.198.112,192.168.198.113,192.168.198.112,192.168.198.113&" +
"gclusterId=gcl1";
发现确实减少了111节点的负载。
哦吼 出大问题
但是如果这样写:多配置两个111的ip
String url = "jdbc:gbase://192.168.198.111:5258/gbase?" +
"user=gbase&" +
"password=gbase20110531&" +
"failoverEnable=true&" +
"hostList=192.168.198.111,192.168.198.111,192.168.198.112,192.168.198.113&" +
"gclusterId=gcl1";
预想中的5个连接一个循环,其中111节点是112、113的3倍并未实现。
这样有用吗?
猜想可能是因为111节点为url中的首要连接,为了防止用户在配置时忘记去除首要节点,而特意过滤掉了对应的ip,为了避免这个特性,经过观察,发现url中带了这样一个配置。
failoverEnable=true
这个是集群的故障转移配置,当连接不通时,集群会寻找相应可用节点连接,话不多说,上验证。
String url = "jdbc:gbase://192.168.198.111:5258/gbase?" +
"user=gbase&" +
"password=gbase20110531&" +
"failoverEnable=true&" +
"hostList=192.168.198.112,192.168.198.113&" +
"gclusterId=gcl1";
我关掉了111机器上的gabse服务
运行结果如下。
果然是两个IP一循环。
果然有用!
所以我们可以利用这个特性将负载配置全部集中在hostList中,只需要给首要节点ip一个非法的ip即可:比如255.255.255.255
如下:
String url = "jdbc:gbase://255.255.255.255:5258/gbase?" +
"user=gbase&" +
"password=gbase20110531&" +
"failoverEnable=true&" +
"hostList=192.168.198.111,192.168.198.112,192.168.198.112,192.168.198.113,192.168.198.113,192.168.198.113&" +
"gclusterId=gcl1";
果然是6个一循环111:112:113 = 1:2:3和配置相同