基于Nginx的軟件負載均衡實現解讀
負載均衡在服務端開發中算是一個比較重要的特性。因為Nginx除了作為常規的Web服務器外,還會被大規模的用于反向代理前端,因為Nginx的異步框架可以處理很大的并發請求,把這些并發請求hold住之后就可以分發給后臺服務端(backend servers,也叫做服務池, 后面簡稱backend)來做復雜的計算、處理和響應,這種模式的好處是相當多的:隱藏業務主機更安全,節約了公網IP地址,并且在業務量增加的時候可以方便地擴容后臺服務器。
負載均衡可以分為硬件負載均衡和軟件負載均衡,前者一般是專用的軟件和硬件相結合的設備,設備商會提供完整成熟的解決方案,通常也會更加昂貴。軟件的復雜均衡以Nginx占據絕大多數,本文也是基于其手冊做相應的學習研究的。
一、基本簡介
負載均衡涉及到以下的基礎知識。
(1) 負載均衡算法
a. RoundRobin: 對所有的backend輪訓發送請求,算是最簡單的方式了,也是默認的分配方式;
b. LeastConnections(least_conn): 跟蹤和backend當前的活躍連接數目,最少的連接數目說明這個backend負載最輕,將請求分配給他,這種方式會考慮到配置中給每個upstream分配的weight權重信息;
c. LeastTime(least_time): 請求會分配給響應最快和活躍連接數最少的backend;
d. IPHash(ip_hash): 對請求來源IP地址計算hash值,IPv4會考慮前3個octet,IPv6會考慮所有的地址位,然后根據得到的hash值通過某種映射分配到backend;
e.Generic Hash(hash): 以用戶自定義資源(比如URL)的方式計算hash值完成分配,其可選consistent關鍵字支持一致性hash特性;
(2) 會話一致性
用戶(瀏覽器)在和服務端交互的時候,通常會在本地保存一些信息,而整個過程叫做一個會話(Session)并用唯一的Session ID進行標識。會話的概念不僅用于購物車這種常見情況,因為HTTP協議是無狀態的,所以任何需要邏輯上下文的情形都必須使用會話機制,此外HTTP客戶端也會額外緩存一些數據在本地,這樣就可以減少請求提高性能了。如果負載均衡可能將這個會話的請求分配到不同的后臺服務端上,這肯定是不合適的,必須通過多個backend共享這些數據,效率肯定會很低下,最簡單的情況是保證會話一致性——相同的會話每次請求都會被分配到同一個backend上去。