一 特點
1.1 應用情況
Nginx做為一個強大的Web伺服器軟體,具有高效能、高併發性和低記憶體佔用的特點。此外,其也能夠提供強大的反向代理功能。俄羅斯大約有超過20%的虛擬主機採用Nginx作為反向代理伺服器,在國內也有騰訊、新浪、網易等多家網站在使用Nginx作為反向代理伺服器。據Netcraft統計,世界上最繁忙的網站中有11.48%使用Nginx作為其伺服器或者代理伺服器。基於反向代理的功能,Nginx作為負載均衡主要有以下幾點理由:
- 高併發連線
- 記憶體消耗少
- 配置檔案非常簡單
- 成本低廉
- 支援Rewrite重寫規則
- 內建的健康檢查功能
- 節省頻寬
- 穩定性高
1.2 架構
上圖為來自官方的一張總體架構圖。
nginx在啟動後,會以daemon的方式在後臺執行,後臺程式包含一個master程式和多個worker程式。工作程式以非特權使用者執行。
master程式主要用來管理worker程式,包含:接收來自外界的訊號,向各worker程式傳送訊號,監控worker程式的執行狀態,當worker程式退出後(異常情況下),會自動重新啟動新的worker程式。
worker程式則是處理基本的網路事件。多個worker程式之間是對等的,他們同等競爭來自客戶端的請求,各程式互相之間是獨立的。一個請求,只可能在一個worker程式中處理,一個worker程式,不可能處理其它程式的請求。
開發模型:epoll和kqueue。
支援的事件機制:kqueue、epoll、rt signals、/dev/poll 、event ports、select以及poll。
支援的kqueue特性包括EV_CLEAR、EV_DISABLE、NOTE_LOWAT、EV_EOF,可用資料的數量,錯誤程式碼.
支援sendfile、sendfile64和sendfilev;檔案AIO;DIRECTIO;支援Accept-filters和TCP_DEFER_ACCEP.
1.3 效能
Nginx的高併發,官方測試支援5萬併發連線。實際生產環境能到2-3萬併發連線數。10000個非活躍的HTTP keep-alive 連線僅佔用約2.5MB記憶體。三萬併發連線下,10個Nginx程式,消耗記憶體150M。淘寶tengine團隊說測試結果是“24G記憶體機器上,處理併發請求可達200萬”。
二 負載均衡
2.1 協議支援
Nginx工作在網路的7層,可以針對http應用本身來做分流策略。支援七層HTTP、HTTPS協議的負載均衡。對四層協議的支援需要第三方外掛-yaoweibin的ngx_tcp_proxy_module實現了tcp upstream。
此外,nginx本身也逐漸在完善對其他協議的支援:
- nginx 1.4.0對Websocket和SPDY都做了正式的支援。
- nginx 1.6.0對SPDY 3.1的正式支援
- nginx 1.10.0正式支援HTTP/2
目前,nginx最新穩定版為1.10.2,主線開發版本已經到了1.11.5。Tengine最新版本則繼承到了nginx的1.6.2版本。
2.2 均衡策略
nginx的負載均衡策略可以劃分為兩大類:內建策略和擴充套件策略。內建策略包含加權輪詢和ip hash,在預設情況下這兩種策略會編譯進nginx核心,只需在nginx配置中指明引數即可。擴充套件策略有很多,如fair、通用hash、consistent hash等,預設不編譯進nginx核心。
加權輪詢(weighted round robin)
輪詢的原理很簡單,首先我們介紹一下輪詢的基本流程。如下是處理一次請求的流程圖:
圖中有兩點需要注意,第一,如果可以把加權輪詢演算法分為先深搜尋和先廣搜尋,那麼nginx採用的是先深搜尋演算法,即將首先將請求都分給高權重的機器,直到該機器的權值降到了比其他機器低,才開始將請求分給下一個高權重的機器;第二,當所有後端機器都down掉時,nginx會立即將所有機器的標誌位清成初始狀態,以避免造成所有的機器都處在timeout的狀態,從而導致整個前端被夯住。
ip hash
ip hash是nginx內建的另一個負載均衡的策略,流程和輪詢很類似,只是其中的演算法和具體的策略有些變化,如下圖所示:
ip hash演算法的核心實現如下:
for(i = 0;i < 3;i++){ hash = (hash * 113 + iphp->addr[i]) % 6271; } p = hash % iphp->rrp.peers->number; 複製程式碼
從程式碼中可以看出,hash值既與ip有關又與後端機器的數量有關。經過測試,上述演算法可以連續產生1045個互異的value,這是該演算法的硬限制。對此nginx使用了保護機制,當經過20次hash仍然找不到可用的機器時,演算法退化成輪詢。因此,從本質上說,ip hash演算法是一種變相的輪詢演算法,如果兩個ip的初始hash值恰好相同,那麼來自這兩個ip的請求將永遠落在同一臺伺服器上,這為均衡性埋下了很深的隱患。
fair
fair策略是擴充套件策略,預設不被編譯進nginx核心。其原理是根據後端伺服器的響應時間判斷負載情況,從中選出負載最輕的機器進行分流。這種策略具有很強的自適應性,但是實際的網路環境往往不是那麼簡單,因此要慎用。
通用hash、一致性hash
這兩種也是擴充套件策略,在具體的實現上有些差別,通用hash比較簡單,可以以nginx內建的變數為key進行hash,一致性hash採用了nginx內建的一致性hash環,可以支援memcache。
session_sticky
此種策略就是一次會話內的請求都會落到同一個結點上。在做分散式架構時可以使用,但是當一個結點掛掉時,會話資訊同時也會丟失,如果使用session同步方案同步session資訊到所有結點的話代價又會很高,慎重使用此方案。nginx預設不支援此種策略,tengine提供了支援: tengine.taobao.org/document_cn….
2.2 配置示例
HTTP
upstream upstream_test{ server 192.168.0.1:8080; server 192.168.0.2:8080; #ip_hash; keepalive 30; ## tengine config #check interval=300 rise=10 fall=10 timeout=100 type=http port=80; #check_http_send "GET / HTTP/1.0\r\n\r\n"; #check_http_expect_alive http_2xx http_3xx; ## tengine config #session_sticky cookie=cookieTest mode=insert; } location / { proxy_pass http://upstream_test; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }複製程式碼
對於nginx更為具體的配置可參考:github.com/superhj1987…
TCP - ngx_tcp_proxy_module
tcp { upstream cluster { #simple round-robin server 192.168.0.1:8080; server 192.168.0.2:8080; check interval=3000 rise=2 fall=5 timeout=1000; #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello; #check interval=3000 rise=2 fall=5 timeout=1000 type=http; #check_http_send "GET / HTTP/1.0\r\n\r\n"; #check_http_expect_alive http_2xx http_3xx; } server { listen 8888; proxy_pass cluster; } }複製程式碼
三 動態負載均衡
3.1 自身監控
內建了對後端伺服器的健康檢查功能。如果Nginx proxy後端的某臺伺服器當機了,會把返回錯誤的請求重新提交到另一個節點,不會影響前端訪問。它沒有獨立的健康檢查模組,而是使用業務請求作為健康檢查,這省去了獨立健康檢查執行緒,這是好處。壞處是,當業務複雜時,可能出現誤判,例如後端響應超時,這可能是後端當機,也可能是某個業務請求自身出現問題,跟後端無關。
3.2 可擴充套件性
Nginx屬於典型的微核心設計,其核心非常簡潔和優雅,同時具有非常高的可擴充套件性。如下圖所示:
Nginx是純C語言的實現,其可擴充套件性在於其模組化的設計。目前,Nginx已經有很多的第三方模組,大大擴充套件了自身的功能。nginx_lua_module可以將Lua語言嵌入到Nginx配置中,從而利用Lua極大增強了Nginx本身的程式設計能力,甚至可以不用配合其它指令碼語言(如PHP或Python等),只靠Nginx本身就可以實現複雜業務的處理。
3.3 配置修改
nginx的配置架構如下圖所示:
Nginx支援熱部署,幾乎可以做到7*24不間斷執行,即使執行數個月也不需要重新啟動。能夠在不間斷服務的情況下,對軟體版本進行進行升級。Nginx的配置檔案非常簡單,風格跟程式一樣通俗易懂,能夠支援perl語法。使用nginx –s reload可以在執行時載入配置檔案,便於執行時擴容/減容。重新載入配置時,master程式傳送命令給當前正在執行的worker程式worker程式接到命令後會在處理完當前任務後退出。同時,master程式會啟動新的worker程式來接管工作。
四 優勢和劣勢
4.1 優勢
- 可以很好地進行http 的頭處理
- 對http協議以及https的良好支援
- 有足夠的第三方外掛供使用
- 支援熱部署,更改後端是平滑的
4.2 劣勢
- 缺少對session的支援
- 對四層tcp的支援不夠好
- post請求寫檔案系統,造成500 error
- 缺乏主動的後端伺服器健康監測
- 預設的監控介面統計資訊不全
五 Tengine
Tengine是淘寶基於nginx開原始碼二次開發一款伺服器軟體,在繼承了nginx的特性以外,提供了一些nginx商業版才有的功能。基本上同步於nginx的更新,目前最新的版本已經繼承了nginx 1.6.2穩定版。
5.1 特性
tengine的特性包括但不限於:
- 更友好的運維資訊顯示
- 動態模組載入機制
- 自動根據CPU數目設定程式個數和繫結CPU親緣性
- 更方便的命令列引數,如列出編譯的模組列表、支援的指令等
- 更加強大的負載均衡能力,包括一致性hash模組、會話保持模組,還可以對後端的伺服器進行主動健康檢查,根據伺服器狀態自動上線下線
- 動態指令碼語言Lua支援。擴充套件功能非常高效簡單
- 輸入過濾器機制支援。通過使用這種機制Web應用防火牆的編寫更為方便
5.2 負載均衡
負載均衡方面,Tengine主要有以下幾個特點,基本上彌補了nginx在負載均衡方面的欠缺:
- 支援一致性Hash模組
- 會話保持模組
- 對後端伺服器的主動健康檢查。
- 增加了請求體不快取到磁碟的機制