前言:前面用nginx+keepalived做了emqx的负载均衡和高可用,但是通过观察服务器监控发现,nginx转发了tcp连接到emq后,还会占着tcp的连接数,这就导致服务器的tcp总连接数翻倍。还有个问题就是,通过nginx转发的tcp连接到emq那显示的ip全部变成了nginx服务器的内网ip,那么通过自己实现负载均衡,就没有这个问题。
那如何自己实现负载均衡,话不多说,先写思路。
我发现在客户端的代码层面,连接地址是可以填一个数组的
mqttConnectOptions.setServerURIs(new String[]{"tcp://192.168.1.135:1883","tcp://192.168.1.136:1883"});
也就是说,客户端会先连接第一个地址,如果连不上,会继续连下一个地址。看过源码和实验证明后,也确实是这样。
那么我每次将这个数组的顺序打乱,2个节点的话55均分,3个节点就1/3均分,那不就是在客户端层面实现了负载均衡了吗!
说干就干,代码如下:
public static void main(String[] args) {
int a = 0;
int b = 0;
int c = 0;
for (int i = 0; i < 100000; i++) {
String[] stringss = {"a","b","c"};
random(stringss);
if ("a".equals(stringss[0])){
a++;
}else if ("b".equals(stringss[0])){
b++;
}else {
c++;
}
}
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
public static void random(String[] arr){
List<String> list = Arrays.asList(arr);
Collections.shuffle(list);
}
集合工具类Collections提供了一个打乱顺序的方法可以直接用,但只针对于集合,所以先转集合再打乱。
以上操作后,成千上万的设备经过打乱,都会比较均匀的分布,自己负载均衡实现完毕。
但这种实现,是在客户端方面做文章,也就是本身能修改客户端的代码才行。如果客户端不是自己控制,那么老老实实用LB服务器做负载均衡吧。