負載均衡 LVS&Nginx

LVS

LVS(Linux Virtual Server)即Linux虛擬服務器,是由章文嵩博士主導的開源負載均衡項目,目前LVS已經被集成到Linux內核模塊中。該項目在Linux內核中實現了基於IP的數據請求負載均衡調度方案,其體系結構如圖1所示,終端互聯網用戶從外部訪問公司的外部負載均衡服務器,終端用戶的Web請求會發送給LVS調度器,調度器根據自己預設的算法決定將該請求發送給後端的某臺Web服務器,比如,輪詢算法可以將外部的請求平均分發給後端的所有服務器,終端用戶訪問LVS調度器雖然會被轉發到後端真實的服務器,但如果真實服務器連接的是相同的存儲,提供的服務也是相同的服務,最終用戶不管是訪問哪臺真實服務器,得到的服務內容都是一樣的,整個集羣對用戶而言都是透明的。最後根據LVS工作模式的不同,真實服務器會選擇不同的方式將用戶需要的數據發送到終端用戶,LVS工作模式分爲NAT模式、TUN模式、以及DR模式。

在這裏插入圖片描述

三種工作模式的解析

基於NAT的LVS模式負載均衡

NAT(Network Address Translation)即網絡地址轉換,其作用是通過數據報頭的修改,使得位於企業內部的私有IP地址可以訪問外網,以及外部用用戶可以訪問位於公司內部的私有IP主機。VS/NAT工作模式拓撲結構如圖2所示,LVS負載調度器可以使用兩塊網卡配置不同的IP地址,eth0設置爲私鑰IP與內部網絡通過交換設備相互連接,eth1設備爲外網IP與外部網絡聯通

  • 用戶通過互聯網DNS服務器解析到公司負載均衡設備上面的外網地址,相對於真實服務器而言,LVS外網IP又稱VIP(Virtual IP Address),用戶通過訪問VIP,即可連接後端的真實服務器(Real Server),而這一切對用戶而言都是透明的,用戶以爲自己訪問的就是真實服務器,但他並不知道自己訪問的VIP僅僅是一個調度器,也不清楚後端的真實服務器到底在哪裏、有多少真實服務器。
  • 用戶將請求發送至124.126.147.168,此時LVS將根據預設的算法選擇後端的一臺真實服務器(192.168.0.1~192.168.0.3),將數據請求包轉發給真實服務器,並且在轉發之前LVS會修改數據包中的目標地址以及目標端口,目標地址與目標端口將被修改爲選出的真實服務器IP地址以及相應的端口。
  • 真實的服務器將響應數據包返回給LVS調度器,調度器在得到響應的數據包後會將源地址和源端口修改爲VIP及調度器相應的端口,修改完成後,由調度器將響應數據包發送回終端用戶,另外,由於LVS調度器有一個連接Hash表,該表中會記錄連接請求及轉發信息,當同一個連接的下一個數據包發送給調度器時,從該Hash表中可以直接找到之前的連接記錄,並根據記錄信息選出相同的真實服務器及端口信息。

在這裏插入圖片描述

基於TUN的LVS負載均衡

在LVS(NAT)模式的集羣環境中,由於所有的數據請求及響應的數據包都需要經過LVS調度器轉發,如果後端服務器的數量大於10臺,則調度器就會成爲整個集羣環境的瓶頸。我們知道,數據請求包往往遠小於響應數據包的大小。因爲響應數據包中包含有客戶需要的具體數據,所以LVS(TUN)的思路就是將請求與響應數據分離,讓調度器僅處理數據請求,而讓真實服務器響應數據包直接返回給客戶端。VS/TUN工作模式拓撲結構如圖3所示。其中,IP隧道(IP tunning)是一種數據包封裝技術,它可以將原始數據包封裝並添加新的包頭(內容包括新的源地址及端口、目標地址及端口),從而實現將一個目標爲調度器的VIP地址的數據包封裝,通過隧道轉發給後端的真實服務器(Real Server),通過將客戶端發往調度器的原始數據包封裝,並在其基礎上添加新的數據包頭(修改目標地址爲調度器選擇出來的真實服務器的IP地址及對應端口),LVS(TUN)模式要求真實服務器可以直接與外部網絡連接,真實服務器在收到請求數據包後直接給客戶端主機響應數據。

在這裏插入圖片描述

基於DR的LVS負載均衡

在LVS(TUN)模式下,由於需要在LVS調度器與真實服務器之間創建隧道連接,這同樣會增加服務器的負擔。與LVS(TUN)類似,DR模式也叫直接路由模式,其體系結構如圖4所示,該模式中LVS依然僅承擔數據的入站請求以及根據算法選出合理的真實服務器,最終由後端真實服務器負責將響應數據包發送返回給客戶端。與隧道模式不同的是,直接路由模式(DR模式)要求調度器與後端服務器必須在同一個局域網內,VIP地址需要在調度器與後端所有的服務器間共享,因爲最終的真實服務器給客戶端迴應數據包時需要設置源IP爲VIP地址,目標IP爲客戶端IP,這樣客戶端訪問的是調度器的VIP地址,迴應的源地址也依然是該VIP地址(真實服務器上的VIP),客戶端是感覺不到後端服務器存在的。由於多臺計算機都設置了同樣一個VIP地址,所以在直接路由模式中要求調度器的VIP地址是對外可見的,客戶端需要將請求數據包發送到調度器主機,而所有的真實服務器的VIP地址必須配置在Non-ARP的網絡設備上,也就是該網絡設備並不會向外廣播自己的MAC及對應的IP地址,真實服務器的VIP對外界是不可見的,但真實服務器卻可以接受目標地址VIP的網絡請求,並在迴應數據包時將源地址設置爲該VIP地址。調度器根據算法在選出真實服務器後,在不修改數據報文的情況下,將數據幀的MAC地址修改爲選出的真實服務器的MAC地址,通過交換機將該數據幀發給真實服務器。整個過程中,真實服務器的VIP不需要對外界可見。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AB2H2i0V-1589860012056)(leanote://file/getImage?fileId=5ec353d102cf350962000007)]

LVS負載均衡調度算法

根據前面的介紹,我們瞭解了LVS的三種工作模式,但不管實際環境中採用的是哪種模式,調度算法進行調度的策略與算法都是LVS的核心技術,LVS在內核中主要實現了一下十種調度算法。

1.輪詢調度

輪詢調度(Round Robin 簡稱’RR’)算法就是按依次循環的方式將請求調度到不同的服務器上,該算法最大的特點就是實現簡單。輪詢算法假設所有的服務器處理請求的能力都一樣的,調度器會將所有的請求平均分配給每個真實服務器。

2.加權輪詢調度

加權輪詢(Weight Round Robin 簡稱’WRR’)算法主要是對輪詢算法的一種優化與補充,LVS會考慮每臺服務器的性能,並給每臺服務器添加一個權值,如果服務器A的權值爲1,服務器B的權值爲2,則調度器調度到服務器B的請求會是服務器A的兩倍。權值越高的服務器,處理的請求越多。

3.最小連接調度

最小連接調度(Least Connections 簡稱’LC’)算法是把新的連接請求分配到當前連接數最小的服務器。最小連接調度是一種動態的調度算法,它通過服務器當前活躍的連接數來估計服務器的情況。調度器需要記錄各個服務器已建立連接的數目,當一個請求被調度到某臺服務器,其連接數加1;當連接中斷或者超時,其連接數減1。

(集羣系統的真實服務器具有相近的系統性能,採用最小連接調度算法可以比較好地均衡負載。)

4.加權最小連接調度

加權最少連接(Weight Least Connections 簡稱’WLC’)算法是最小連接調度的超集,各個服務器相應的權值表示其處理性能。服務器的缺省權值爲1,系統管理員可以動態地設置服務器的權值。加權最小連接調度在調度新連接時儘可能使服務器的已建立連接數和其權值成比例。調度器可以自動問詢真實服務器的負載情況,並動態地調整其權值。

5.基於局部的最少連接

基於局部的最少連接調度(Locality-Based Least Connections 簡稱’LBLC’)算法是針對請求報文的目標IP地址的 負載均衡調度,目前主要用於Cache集羣系統,因爲在Cache集羣客戶請求報文的目標IP地址是變化的。這裏假設任何後端服務器都可以處理任一請求,算法的設計目標是在服務器的負載基本平衡情況下,將相同目標IP地址的請求調度到同一臺服務器,來提高各臺服務器的訪問局部性和Cache命中率,從而提升整個集羣系統的處理能力。LBLC調度算法先根據請求的目標IP地址找出該目標IP地址最近使用的服務器,若該服務器是可用的且沒有超載,將請求發送到該服務器;若服務器不存在,或者該服務器超載且有服務器處於一半的工作負載,則使用’最少連接’的原則選出一個可用的服務器,將請求發送到服務器。

6.帶複製的基於局部性的最少連接

帶複製的基於局部性的最少連接(Locality-Based Least Connections with Replication 簡稱’LBLCR’)算法也是針對目標IP地址的負載均衡,目前主要用於Cache集羣系統,它與LBLC算法不同之處是它要維護從一個目標IP地址到一組服務器的映射,而LBLC算法維護從一個目標IP地址到一臺服務器的映射。按’最小連接’原則從該服務器組中選出一一臺服務器,若服務器沒有超載,將請求發送到該服務器;若服務器超載,則按’最小連接’原則從整個集羣中選出一臺服務器,將該服務器加入到這個服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服務器從服務器組中刪除,以降低複製的程度。

7.目標地址散列調度

目標地址散列調度(Destination Hashing 簡稱’DH’)算法先根據請求的目標IP地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且並未超載,將請求發送到該服務器,否則返回空。

8.源地址散列調度U

源地址散列調度(Source Hashing 簡稱’SH’)算法先根據請求的源IP地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且並未超載,將請求發送到該服務器,否則返回空。它採用的散列函數與目標地址散列調度算法的相同,它的算法流程與目標地址散列調度算法的基本相似。

9.最短的期望的延遲

最短的期望的延遲調度(Shortest Expected Delay 簡稱’SED’)算法基於WLC算法。舉個例子吧,ABC三臺服務器的權重分別爲1、2、3 。那麼如果使用WLC算法的話一個新請求進入時它可能會分給ABC中的任意一個。使用SED算法後會進行一個運算

A:(1+1)/1=2 B:(1+2)/2=3/2 C:(1+3)/3=4/3 就把請求交給得出運算結果最小的服務器。

10.最少隊列調度

最少隊列調度(Never Queue 簡稱’NQ’)算法,無需隊列。如果有realserver的連接數等於0就直接分配過去,不需要在進行SED運算。

Nginx

負載均衡用於從“upstream”模塊定義的後端服務器列表中選取一臺服務器接受用戶的請求。一個最基本的upstream模塊是這樣的,模塊內的server是服務器列表:

#動態服務器組
    upstream dynamic_zuoyu {
        server localhost:8080;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082;  #tomcat 8.5
        server localhost:8083;  #tomcat 9.0
    }

在upstream模塊配置完成後,要讓指定的訪問反向代理到服務器列表:

#其他頁面反向代理到tomcat容器
        location ~ .*$ {
            index index.jsp index.html;
            proxy_pass http://dynamic_zuoyu;
        }

這就是最基本的負載均衡實例,但這不足以滿足實際需求;目前Nginx服務器的upstream模塊支持6種方式的分配:
 負載均衡策略

輪詢 默認方式
weight 權重方式
ip_hash 依據ip分配方式
least_conn 最少連接方式
fair(第三方) 響應時間方式
url_hash(第三方) 依據URL分配方式

輪詢

最基本的配置方法,上面的例子就是輪詢的方式,它是upstream模塊默認的負載均衡默認策略。每個請求會按時間順序逐一分配到不同的後端服務器。

fail_timeout 與max_fails結合使用。
max_fails 設置在fail_timeout參數設置的時間內最大失敗次數,如果在這個時間內,所有針對該服務器的請求都失敗了,那麼認爲該服務器會被認爲是停機了,
fail_time 服務器會被認爲停機的時間長度,默認爲10s。
backup 標記該服務器爲備用服務器。當主服務器停止時,請求會被髮送到它這裏。
down 標記服務器永久停機了。

注意:

  • 在輪詢中,如果服務器down掉了,會自動剔除該服務器。
  • 缺省配置就是輪詢策略。
  • 此策略適合服務器配置相當,無狀態且短平快的服務使用。

weight

權重方式,在輪詢策略的基礎上指定輪詢的機率。例子如下:

#動態服務器組
    upstream dynamic_zuoyu {
        server localhost:8080   weight=2;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082   backup;  #tomcat 8.5
        server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 9.0
    }
    

在該例子中,weight參數用於指定輪詢機率,weight的默認值爲1,;weight的數值與訪問比率成正比,比如Tomcat 7.0被訪問的機率爲其他服務器的兩倍。

注意:

  • 權重越高分配到需要處理的請求越多。
  • 此策略可以與least_conn和ip_hash結合使用。
  • 此策略比較適合服務器的硬件配置差別比較大的情況。

ip_hash

指定負載均衡器按照基於客戶端IP的分配方式,這個方法確保了相同的客戶端的請求一直髮送到相同的服務器,以保證session會話。這樣每個訪客都固定訪問一個後端服務器,可以解決session不能跨服務器的問題。

#動態服務器組
    upstream dynamic_zuoyu {
        ip_hash;    #保證每個訪客固定訪問一個後端服務器
        server localhost:8080   weight=2;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082;  #tomcat 8.5
        server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 9.0
    }

注意:

  • 在nginx版本1.3.1之前,不能在ip_hash中使用權重(weight)。
  • ip_hash不能與backup同時使用。
  • 此策略適合有狀態服務,比如session。
  • 當有服務器需要剔除,必須手動down掉。

least_conn

把請求轉發給連接數較少的後端服務器。輪詢算法是把請求平均的轉發給各個後端,使它們的負載大致相同;但是,有些請求佔用的時間很長,會導致其所在的後端負載較高。這種情況下,least_conn這種方式就可以達到更好的負載均衡效果。

#動態服務器組
    upstream dynamic_zuoyu {
        least_conn;    #把請求轉發給連接數較少的後端服務器
        server localhost:8080   weight=2;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082 backup;  #tomcat 8.5
        server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 9.0
    }

注意:

  • 此負載均衡策略適合請求處理時間長短不一造成服務器過載的情況。

第三方策略

fair

按照服務器端的響應時間來分配請求,響應時間短的優先分配。

#動態服務器組
    upstream dynamic_zuoyu {
        server localhost:8080;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082;  #tomcat 8.5
        server localhost:8083;  #tomcat 9.0
        fair;    #實現響應時間短的優先分配
    }

url_hash

按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,要配合緩存命中來使用。同一個資源多次請求,可能會到達不同的服務器上,導致不必要的多次下載,緩存命中率不高,以及一些資源時間的浪費。而使用url_hash,可以使得同一個url(也就是同一個資源請求)會到達同一臺服務器,一旦緩存住了資源,再此收到請求,就可以從緩存中讀取。

#動態服務器組
    upstream dynamic_zuoyu {
        hash $request_uri;    #實現每個url定向到同一個後端服務器
        server localhost:8080;  #tomcat 7.0
        server localhost:8081;  #tomcat 8.0
        server localhost:8082;  #tomcat 8.5
        server localhost:8083;  #tomcat 9.0
    }

總結

以上便是6種負載均衡策略的實現方式,其中除了輪詢和輪詢權重外,都是Nginx根據不同的算法實現的。在實際運用中,需要根據不同的場景選擇性運用,大都是多種策略結合使用以達到實際需求。

參考:

LVS負載均衡
Nginx服務器之負載均衡策略(6種)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章