zookeeper本身是不提供負載均衡的策略,需要自己來實現,所以這里確切的說,是在負載均衡中應用到了zookeeper做集群的協調。
對於HTTP請求的負載均衡,成熟的解決方案是Nginx(或Haproxy) +keepalived。其中Niginx負責代理HTTP請求,通過某種均衡策略訪問集群中的服務器,keepalived負責檢測集群中的服務器運行情況(有故障的機器移除,機器恢復工作后重新加入)
而對於TCP層的負載均衡,比如用Apache Mina做的網絡通信應用,上面那種方案明顯不適合,因為網絡通信客戶端和服務端要保持長連接
所以要針對這種長連接做負載均衡,一般都是基於連接數這種均衡策略,也就是在第一次連接時,分配服務器IP時,取當前連接數最少的那台
集群中有幾台服務器處於運行狀態,每一台服務器當前連接的客戶數量,最大連接數量,等等這些信息需要記錄起來,然后每次做負載均衡時根據這些信息來做分配,一般首先想到的是把這些信息存放在數據庫里
簡單的做法就是服務器啟動時,把數據庫里相應的狀態改為運行,有客戶連接或斷開時,把連接數做加數或減數運算。
當服務器關閉時,問題就來了:
1、服務器關閉,可能數據源也已經被關閉,沒法操作數據庫,該機器在數據庫里一直處於運行狀態
2、服務器宕機,這種問題就很致命,這是連關閉的程序都沒有執行,更不用說能操作數據庫了
解決的方式就是用zookeeper保存服務器的連接信息
1、當服務器啟動時,往zookeeper的節點里寫入數據(節點類型是臨時節點)
2、當服務器關閉時,從zookeeper移除相應的節點數據
3、當服務器宕機,zookeeper因為沒有檢測到心跳,自動把該節點移除,並通知其他服務器,其他服務器得知該機器已宕機,在分配連接時,不會分配到這台機器上,這點也是標題說的在負載均衡中用到zookeeper的原因。
對比了一下保存在數據庫那種方式,zookeeper其實就是一個具有通知功能的數據庫,也就是它底下節點數據有變化時,會通知它的所有客戶端(這里的客戶端指的連接到zookeeper的服務器)。