負載均衡排程器最大程度地讓使用者不必關心後端伺服器,我們知道,當採用RR排程策略時,即便是同一使用者對同一內容的多次請求,也可能被轉發到了不同的後端伺服器,這聽起來似乎沒什麼大礙,但有時候,或許會帶來一些問題。
當某臺後端伺服器啟用了Session來本地化儲存使用者的一些資料後,下次使用者的請求如果轉發給了其他後端伺服器,將導致之前的Session資料無法訪問;
後端伺服器實現了一定的動態內容快取,而毫無規律的轉發使得這些快取的利用率下降。
如何解決這些問題呢?從表面上看,我們需要做的就是調整排程策略,讓使用者在一次會話週期內的所有請求始終轉發到一臺特定的後端伺服器上,這種機制也稱為黏滯會話(Sticky Sessions),要實現它的關鍵在於如何設計持續性排程演算法。
既然要讓排程器可以識別使用者,那麼將使用者的IP地址作為識別標誌最為合適,一些反向代理伺服器對此都有支援,比如Nginx和HAProxy,它們可以將使用者的IP地址進行Hash計算並雜湊到不同的後端伺服器上。
對於Nginx,只需要在upstream中宣告ip_hash即可,如下所示:
upstream backend {
ip_hash;
server 10.0.1.200:80;
server 10.0.1.201:80;
}
除此之外,你還可以利用Cookies機制來設計永續性演算法,比如排程器將某個後端伺服器的編號追加到寫給使用者的Cookies中,這樣排程器便可以在該使用者隨後的請求中知道應該轉發給哪臺後端伺服器。這樣做可以更加細粒度地追蹤到每一個使用者,試想一下,當有很多使用者隱藏在一個公開IP地址後面時,利用Cookies的永續性演算法將顯得更加有效。
我們已經實現了黏滯會話,但是如此一來,黏滯會話可能或多或少地破壞了均衡策略,至少像權重分配這樣的動態策略已經無法工作,我們對此不能視而不見,否則前面的努力即將付諸東流。
當然,問題的關鍵在於,我們究竟是否要通過實現黏滯會話來遷就係統的特殊需要呢?在權衡代價之後你認為是否值得呢?最為關鍵的問題是前面提到的兩個問題是否能從根本上避免呢?如果可以,這很值得去考慮。
事實上,在後端伺服器上儲存Session資料和本地化快取,的確是一件不明智的事情,它使得後端伺服器顯得過於個性化,以至於和整個系統格格不入,如果允許的話,我們應該儘量避免這樣的設計,比如採用分散式Session或者分散式快取等,讓後端伺服器的應用盡量與本地無關,也可更好地適應環境。