Nginx怎么使用ngx_http_upstream_module實現負載均衡功能

    負載均衡介紹

    什么是負載均衡

    負載均衡(load balance),意思是將負載(工作任務,訪問請求)進行平衡、分攤到多個操作單元(服務器,組件)上進行執行。

    為什么需要負載均衡

    當單臺web服務器直接面向用戶,可能要承載著大量的并發請求,單臺服務器可能難以負荷,我們需要使用多臺web服務器組成一個集群,利用nginx負載均衡功能,將請求分發給不同的后端服務器,實現負載的流量分發,提升整體性能、以及系統的容災能力。

    • 負載均衡與代理有什么區別

    代理是代理一臺服務器基于URI調度,調度到不同功能的應用節點

    負載均衡是將客戶端請求通過proxy_pass代理至一組upstream資源池

    • 實現負載均衡場景

    實現負載均衡功能需要使用兩個模塊:

    • proxy_pass:代理模塊

    • upstream:虛擬資源池

    示例:一個官方的的負載均衡展示

    upstream?backend?{ ????server?backend1.example.com???????weight=5; ????server?backend2.example.com:8080; ????server?unix:/tmp/backend3;  ????server?backup1.example.com:8080???backup; ????server?backup2.example.com:8080???backup; }  server?{ ????location?/?{ ????????proxy_pass?http://backend; ????} }

    示例:自己完成一個小例子

    upstream?node?{ ????server?192.168.10.3:80; ????server?192.168.10.4:80; } server?{ ????listen?80; ????server_name?www.yyang.com; ????location?/?{ ????????proxy_pass?http://node; ????????include?prxoy_params; ????} }

    負載均衡調度算法

    輪詢調度

    按順序逐一分配到不同的后端節點,也是默認算法。(簡單來說就是1:1:1)

    加權輪詢
    考慮到不同服務器的性能不同,給予節點不同的權值,使其接收到相應的權值請求數

    server?192.168.10.3:80?weight=3; server?192.168.10.4:80?weight=1;

    以上這個例子是說每4個請求會分配給10.3三個,10.4一個,以此循環

    ip_hash

    根據用戶請求的IP,對該IP進行hash運算,根據運算的值將請求分配給后端特定的一臺節點進行處理。

    取值范圍為ipv4地址的前三個8位或ipv6的整個地址作為哈希鍵,確保來自從一個客戶端的IP始終傳遞給同一臺服務器,除非次服務器不可用。簡單點說,172.16.20.1和172.16.20.2的前三組數字是一樣的(都是172.16.20)

    ip_hash運算公式:hash(ip)%node_counts=index

    ip_hash帶來的問題:
    大量同一IP的請求會造成某個節點流量過大
    如果臨時下線一臺節點,會重新計算hash值,建議使用down狀態

    示例:注意ip_hash與權重不可同時使用

    ip_hash; server?192.168.10.3:80; server?192.168.10.4:80;

    一致性hash

    為了避免上述問題,所以誕生了一致性hash,使用取模的方式,但不對服務器節點數量取模,而是對2的32次方取模,hash函數值為0~2^32-1。(形成一個虛擬圓環,用戶請求會發給順時針相鄰的節點)
    有一個問題:如果后端節點較少可能會造成數據傾斜,所以一致性hash引入了虛擬節點機制,即對每個服務器計算多個哈希,每個計算結果位置都放置一個虛擬節點。
    如果我們想使用ip_hash,但是計算公式使用一致性hash,該怎么做?

    hash?$remote_addr?consistent; server?192.168.10.3:80; server?192.168.10.4:80;

    url_hash

    根據用戶的url進行hash取模,根據運算值,將請求分配給一臺特定的后端服務器。

    1.用戶請求nginx負載均衡,通過url算法,請求調度至cache1
    2.cache1沒有數據,會向后端獲取,返回數據,并將數據緩存
    3.當其他用戶訪問相同url時,調度器依然會調度到cache1節點
    4.cache1會直接將數據返回

    hash?$request_uri?consistent; server?192.168.10.3:80; server?192.168.10.4:80;

    least_conn

    哪臺服務器的連接數最少,就將請求調度到這臺服務器

    least_conn; server?192.168.10.3:80; server?192.168.10.4:80;

    負載均衡后端節點狀態

    down

    將服務器節點標記為不可用狀態,一般用于停機維護。

    server?192.168.10.3:80?down; server?192.168.10.4:80;

    backup

    備用節點,正常情況不會調度到此節點;當正常工作節點全部不可用時,會啟用此節點;當節點恢復時此節點會繼續恢復備用狀態。

    server?192.168.10.3:80; server?192.168.10.4:80; server?192.168.10.5:80?backup;

    max_conns

    用來限制每個后端節點接收到的最大的TCP連接數,如果超出限制就會拋出錯誤。

    server?192.168.10.3:80?max_conns=10; server?192.168.10.4:80?max_conns=10;

    一臺可以連接10.兩臺是20,超過20就會出錯。

    keepalived

    與后端服務器激活緩存,也就是長鏈接,提升網站吞吐量。
    默認不啟用此功能,當有請求時,會建立連接,維護連接,關閉連接,所以會存在網絡消耗;但是如果所有連接都緩存了,當連接空閑了又會占用其他系統資源,所以可以使用keepalived參數。

    server?192.168.10.3:80; server?192.168.10.4:80;  keepalived?32;???#?最大空閑連接數的個數 keepalived_timeout?100s;?#?空閑連接的超時時間  #?需要配合以下兩個參數使用  proxy_http_version?1.1; proxy_set_header?connection?"";

    max_fails與fail_timeout

    max_fails=2:服務器通信失敗兩次,認為服務器不可用
    fail_timeout=5s:服務器通信失敗后,每5秒探測一次服務器是否恢復正常。
    在fail_timeout設定時間內,與服務器連接失敗次數達到max_fails數量,則認為服務器不可用。
    如果不設置的話默認是探測一次,間隔10s。

    server?192.168.10.3:80?max_fails=2?fail_timeout=5s; server?192.168.10.4:80?max_fails=2?fail_timeout=5s;

    ? 版權聲明
    THE END
    喜歡就支持一下吧
    點贊14 分享