Nginx負載均衡與反向代理——基礎功能


熟悉Nginx的小伙伴都知道,Nginx是一個非常好的負載均衡器。除了用的非常普遍的Http負載均衡,Nginx還可以實現Email,FastCGI的負載均衡,甚至可以支持基於Tcp/UDP協議的各種應用的負載均衡(比如MySQL,DNS等)。這些功能分別在Nginx的不同模塊實現了。負載均衡可以看成Nginx對外提供的一種服務。

我們先來簡單介紹下Nginx負載均衡的基本的功能。並且,我們在下面的介紹中會同時羅列Nginx Plus(Nginx的擴展板,部分功能收費)

介紹

在多個應用程序實例之間做負載平衡是一種常用的優化資源利用、最大化吞吐量、減少延遲和確保容錯配置的技術。而使用Nginx可以作為一個高效的Http負載均衡器將流量分攤到各個服務器上,從而改善性能,增加擴展性和可靠性。

簡單配置

負載均衡的基本配置十分的簡單,在基本配置上,你可以添加更多的指令來滿足自己個性化的需求。
如下:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

上面,所有的請求都將被代理到服務器組myapp1上,myapp1上有三台服務器srv1-srv3,這三台服務器將要分攤請求。如果沒有指定負載均衡方法,那么默認的方法是round-robin。
在nginx中,HTTP,HTTPS,FastCGI,uwsgi,SCGI都可以做反向代理,並且可以做負載均衡,上面的例子是http的。要使用https的負載均衡,簡單的將http改為https即可。

負載均衡的常用算法

負載均衡的方法,
就是Http請求如何被分配到各個服務器上的算法。常用的負載均衡的常用算法有以下種:

  • Round‑Robin 默認的方法,也是最簡單的一種。即Http請求按照服務器列表羅列的順序一次進行分配;
  • Least Connections 在這種方式下,每個請求被發送到當下具有最小有效連接數的服務器上,當然權重也會被考慮進去。比如當下有三台服務器A/B/C,當下各自的連接數是100/200/300,那么下一個請求過來就會被分配到A服務器進行處理
  • Hash 用戶定義一個Hash的Key值,比如IP或者URL,將這個Hash的Key和服務器做一次映射,每次請求過來都會按照這個映射被分配到同一台服務器
  • IP Hash (僅適用於Http負載均衡的情況),根據客戶端IP的前三個字節(比如IP是10.25.2.10那么就拿10.25.2做映射)來分配請求,這個和上一種類似
  • Least Time 即最少時間。新的請求將被發往擁有最快響應時間和最少連接數的上游服務器。這是Nginx Plus才具有的方式

最少連接算法

即Least Connections這種算法。最少連接,顧名思義,就是當下誰的連接數最少請求就然該誰來處理。這是一種相對公平的方式,防止某些服務器負載過重,將請求分配到相對“清閑”的服務器上去。基本的配置如下:

upstream myapp1 {
        least_conn;
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
}

需要指定least_conn指令。

Session一致性問題

如果負載均衡采用round-robin或者least-connected算法,同一個客戶端發送過來的不同請求就有可能被不同的server處理,這種情形下就不能保證兩次請求session的一致性。
為了解決這個問題,可以采用第三種負載均衡的算法,那就是ip-hash。有了IP哈希,將客戶端的IP和服務器組列表的幾個服務器之間建立一種對應關系,那么每個客戶端的每次請求就只能被分配到一台server上面,從而保證session的一致性。ip-hash的方式配置如下:

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

負載均衡權重

說是負載"均衡",但是不是說每個server的分配的請求是完全一樣。前面討論的各個服務器組,里面的各個server其實是地位平等、利益均沾。事實上,由於每個server的特性可能不一樣,有些server硬件條件好,穩定性高,理應多處理些請求,相反另一些不太穩定的server就應該適當的少分配請求。我們可以為這些server分配不同的權重,來定義它們在處理請求時所扮演角色的重要性。權重用指令weight來表示,權重高表示選擇的幾率更大,權重低表示選中的幾率更小,權重為0表示始終不選用。以round-robin算法為例:

upstream myapp1 {
        server srv1.example.com weight=3;
        server srv2.example.com;
        server srv3.example.com;
}

沒有weight指令的默認其為1。如果有5個請求過來,理想情況下srv1就能接到3個,srv2和srv3各一個。

服務器健康檢查

反向代理的各種實現(如http/https/FastCGI)還可以對各個server做健康檢查。如果請求一個server錯誤(如返回500,究竟如何才為“失效”,在Nginx Plus中做了擴展),nginx就將這個server標記為失效的,在接下來一段時間的請求中就會避免選擇這台server。究竟這端時間要多長才合適?有max_fails和fail_timeout參數來定義。

  • max_fails
    默認是1,表示在fail_timeout時間內,有多少次對某個server的訪問失敗,就算作這台server的正式失效(你總要給人家多表現幾次的機會撒),默認情況下就是1次;

  • fail_timeout
    默認是10s,有兩層含義,一就是為max_fails指令限定一個時間范圍,二就是如果server已經被標記為失效,那么過了這個時間后,你就應該分配個請求去試探下這個server,是否已經可用了(你總的給人家重新做人的機會)。如果還是不可用,那么此server繼續被標記為失效的server,如果已經可用了那么就重新標記為活躍,在接下來的請求中,繼續按照round-robin/ip-hash等算法和權重給它分配請求,和平常無異。

除了這些指令之外proxy_next_upstream, backup, down, 和 keepalive 也針對負載均衡功能做了不同的限定。

以上這些功能是基本是Nginx的免費版本提供的,其實負載均衡里可以說的話題還多着呢。我們下篇文章中談談Nginx Plus提供的更為豐富的負載均衡的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM