Nginx負載均衡

一 特色

1.1 應用狀況

Nginx作爲一個強大的Web服務器軟件,具備高性能、高併發性和低內存佔用的特色。此外,其也可以提供強大的反向代理功能。俄羅斯大約有超過20%的虛擬主機採用Nginx做爲反向代理服務器,在國內也有騰訊、新浪、網易等多家網站在使用Nginx做爲反向代理服務器。據Netcraft統計,世界上最繁忙的網站中有11.48%使用Nginx做爲其服務器或者代理服務器。基於反向代理的功能,Nginx做爲負載均衡主要有如下幾點理由:php

  1. 高併發鏈接
  2. 內存消耗少
  3. 配置文件很是簡單
  4. 成本低廉
  5. 支持Rewrite重寫規則
  6. 內置的健康檢查功能
  7. 節省帶寬
  8. 穩定性高

1.2 架構

上圖爲來自官方的一張整體架構圖。html

nginx在啓動後,會以daemon的方式在後臺運行,後臺進程包含一個master進程和多個worker進程。工做進程以非特權用戶運行。前端

master進程主要用來管理worker進程,包含:接收來自外界的信號,向各worker進程發送信號,監控worker進程的運行狀態,當worker進程退出後(異常狀況下),會自動從新啓動新的worker進程。nginx

worker進程則是處理基本的網絡事件。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求,各進程互相之間是獨立的。一個請求,只可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。git

開發模型:epoll和kqueue。github

支持的事件機制: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。

github.com/yaoweibin/n…

此外,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內核。

  1. 加權輪詢(weighted round robin)

    輪詢的原理很簡單,首先咱們介紹一下輪詢的基本流程。以下是處理一次請求的流程圖:

    圖中有兩點須要注意,第一,若是能夠把加權輪詢算法分爲先深搜索和先廣搜索,那麼nginx採用的是先深搜索算法,即將首先將請求都分給高權重的機器,直到該機器的權值降到了比其餘機器低,纔開始將請求分給下一個高權重的機器;第二,當全部後端機器都down掉時,nginx會當即將全部機器的標誌位清成初始狀態,以免形成全部的機器都處在timeout的狀態,從而致使整個前端被夯住。

  2. 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的請求將永遠落在同一臺服務器上,這爲均衡性埋下了很深的隱患。

  3. fair

    fair策略是擴展策略,默認不被編譯進nginx內核。其原理是根據後端服務器的響應時間判斷負載狀況,從中選出負載最輕的機器進行分流。這種策略具備很強的自適應性,可是實際的網絡環境每每不是那麼簡單,所以要慎用。

  4. 通用hash、一致性hash

    這兩種也是擴展策略,在具體的實現上有些差異,通用hash比較簡單,能夠以nginx內置的變量爲key進行hash,一致性hash採用了nginx內置的一致性hash環,能夠支持memcache。

  5. session_sticky

    此種策略就是一次會話內的請求都會落到同一個結點上。在作分佈式架構時可使用,可是當一個結點掛掉時,會話信息同時也會丟失,若是使用session同步方案同步session信息到全部結點的話代價又會很高,慎重使用此方案。nginx默認不支持此種策略,tengine提供了支持: tengine.taobao.org/document_cn….

2.2 配置示例

  1. 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…

  2. 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 優點

  1. 能夠很好地進行http 的頭處理
  2. 對http協議以及https的良好支持
  3. 有足夠的第三方插件供使用
  4. 支持熱部署,更改後端是平滑的

4.2 劣勢

  1. 缺乏對session的支持
  2. 對四層tcp的支持不夠好
  3. post請求寫文件系統,形成500 error
  4. 缺少主動的後端服務器健康監測
  5. 默認的監控界面統計信息不全

五 Tengine

Tengine是淘寶基於nginx開源代碼二次開發一款服務器軟件,在繼承了nginx的特性之外,提供了一些nginx商業版纔有的功能。基本上同步於nginx的更新,目前最新的版本已經繼承了nginx 1.6.2穩定版。

5.1 特性

tengine的特性包括但不限於:

  1. 更友好的運維信息顯示
  2. 動態模塊加載機制
  3. 自動根據CPU數目設置進程個數和綁定CPU親緣性
  4. 更方便的命令行參數,如列出編譯的模塊列表、支持的指令等
  5. 更增強大的負載均衡能力,包括一致性hash模塊、會話保持模塊,還能夠對後端的服務器進行主動健康檢查,根據服務器狀態自動上線下線
  6. 動態腳本語言Lua支持。擴展功能很是高效簡單
  7. 輸入過濾器機制支持。經過使用這種機制Web應用防火牆的編寫更爲方便

5.2 負載均衡

負載均衡方面,Tengine主要有如下幾個特色,基本上彌補了nginx在負載均衡方面的欠缺:

  1. 支持一致性Hash模塊
  2. 會話保持模塊
  3. 對後端服務器的主動健康檢查。
  4. 增長了請求體不緩存到磁盤的機制

閱讀原文

相關文章
相關標籤/搜索