前言:前面用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服務器做負載均衡吧。