天天看點

nginx upstream 排程政策

之前一直使用nginx 的upstream,今天有個哥們問我,upstream的調動算法是什麼,我說我還真沒注意過,使用Haproxy的時候倒是注意過,回來一查,原來也是round-robin,下面是nginx 官方文檔給出的說明:

This module provides simple load-balancing (round-robin and client IP) across backend servers.

Example:

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

輪詢排程算法(Round-Robin Scheduling)

  輪詢排程算法的原理是每一次把來自使用者的請求輪流配置設定給内部中的伺服器,從1開始,直到N(内部伺服器個數),然後重新開始循環。

  算法的優點是其簡潔性,它無需記錄目前所有連接配接的狀态,是以它是一種無狀态排程。

  輪詢排程算法流程

  假設有一組伺服器N台,S = {S1, S2, …, Sn},一個訓示變量i表示上一次選擇的伺服器ID。變量i被初始化為N-1。其算法如下: 

j = i;
do
{
	j = (j + 1) mod n;
	i = j;
	return Si;
} while (j != i);

return NULL; 
           

當然nginx也不止round-robin 這一種政策還有ip_hash 一種,這種好處就是一個ip總是被轉發同一server; 

ip_hash

syntax: ip_hash

default: none

context: upstream

This directive causes requests to be distributed between upstreams based on the IP-address of the client. 

The key for the hash is the class-C network address of the client. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server.

It is not possible to combine ip_hash and weight methods for connection distribution. If one of the servers must be removed for some time, you must mark that server as *down*.

For example:

upstream backend {        
ip_hash;        
server   backend1.example.com;       
server   backend2.example.com;       
server   backend3.example.com  down;        
server   backend4.example.com;      
}      

子產品官方介紹:

http://wiki.nginx.org/HttpUpstreamModule

http://www.howtocn.org/nginx:Nginx%E6%A8%A1%E5%9D%97%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88

說說upstream裡的server指令

server後面可以是域名格式,也可以是socket格式[ip:port],後面還可以帶參數。參數有下面幾個:

weight = NUMBER - 設定伺服器的權重值,預設為1. 值越大,配置設定的請求越多。隻适用于輪詢這種LB政策。

max_fails = NUMBER - 

在fail_timeout設定的時間内,嘗試連接配接伺服器失敗的次數.預設為1,0表示關閉檢查.錯誤類型在proxy_next_upstream 

or fastcgi_next_upstream中定義,(除了404錯誤不計入max_fails).

fail_timeout = TIME - the time during which must occur *max_fails* number of unsuccessful attempts at communication with the server that would cause the server to be considered inoperative, and also the time for which the server will be considered inoperative (before another attempt is made). If not set the time is 10 seconds. fail_timeout has nothing to do with upstream response time, use proxy_connect_timeout and proxy_read_timeout for controlling this.

down - marks server as permanently offline, to be used with the directive ip_hash.

backup - (0.6.7 or later) only uses this server if the non-backup servers are all down or busy (cannot be used with the directive ip_hash)

nginx負載均衡的政策:

1.輪詢(預設方式)

對于一級後端伺服器群,形成一個環隊列的形式,對于每個到達的請求按時間順序順次配置設定給這些後端伺服器。在前端排程器與後端伺服器之間采用“心跳”方式進行狀态檢查,如果發現後端伺服器當機,則将其删除。

    這種方式為預設配置,優點是簡潔,但缺點是無法進行最優化排程,有可能有的請求需要耗時較久,這樣會帶來一定的不平衡。

    它的例子:在http區域裡添加:

upstream lb {

        server 10.10.57.122:80;

        server 10.10.57.123:80;

}

在你的某個server裡增加:

location / {

              proxy_pass http://lb;

        }

2. 權重輪詢

    這是一種對上述方式的改進,引入權值的概念,能夠解決後端伺服器性能不均的情況。

    例如這樣一個配置:

    upstream lb {

         server 10.10.57.122:80 weight=5;

         server 10.10.57.123:80 weight=10;

    }

ps:以上輪詢負載均衡政策,我個人認為對于動态網站應用,這幾乎就是形同擺設,沒有人會采用。但一種情況例外:伺服器端的session采用共享機制,如存儲在資料庫或者memcached記憶體裡等。

3. ip_hash(基于ip的hash配置設定政策)

     這是一種非輪詢式方式,對于每個到達的請求,直接通過其請求IP進行哈希的映射,通過映射結果獲得那一台後端伺服器要處理這個請求,這種方式有一個明顯的好處是能夠保證session的唯一性。

    它的配置例子:

upstream lb {

        ip_hash;

        server 10.10.57.122:80;

        server 10.10.57.123:80;

}

在你的某個server裡增加:

location / {

proxy_pass http://lb;

}

This directive causes requests to be distributed between upstreams based on the IP-address of the client. 

The key for the hash is the class-C network address of the client. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server.

It is not possible to combine ip_hash and weight methods for connection distribution. If one of the servers must be removed for some time, you must mark that server as *down*.

由這段英文解說知道,用戶端隻要來自同一網段的ip的request都會轉發到相同的後端伺服器上。這裡的所謂的class-C 

network這裡作者并沒有很詳細地解釋,我隻能說,寫這句話的人不懂網絡。我個人的了解是:以ip位址的點分十進制格式的前3個位元組進行hash。

其實這不是真正意義上的ip address hash,而隻是network address hash。真正的ip address hash方式有不?其實可以通過下面介紹的url_hash來實作。關鍵指令:hash $remote_addr;

不過這裡有個前提,$remote_addr必須是client的real ip address。

為什麼這裡能夠實作真正意義上的ip address hash?很簡單,就是這裡整個ip address被當作一個字元串來對待,故隻要ip位址(key)不同,hash必然也是不同的。

4. url_hash(基于URL的哈希方式)    

這種方式與IP的哈希方式類似,是對客戶機請求的URL進行哈希操作,這樣的方式有一個明顯的好處是,能夠便于内容緩存的實作,對于經常性的資源通路,采

用這樣的方式會獲得非常好的品質。它目前不是nginx自帶的功能,需要安裝更新檔方可使用。本指令的詳細說明和安裝見:(文章後面有附帶詳細安裝執行個體)

http://wiki.nginx.org/HttpUpstreamRequestHashModule

    它的配置方式為:

upstream lb {

         server 10.10.57.122:80;

         server 10.10.57.123:80;

         hash $request_uri;

}

如果将這裡的$request_uri換成$remote_addr便可實作上面我所說的真正基于ip位址的政策。

5. 基于服務響應式

 這種方式是根據伺服器端的動态響應,對每一個請求進行配置設定。 這種方式能夠自動根據目前的後端實際負載來優化。

   它的配置方式:

upstream lb {

         server 10.10.57.122:80;

         server 10.10.57.123:80;

         fair;

    }

這個沒怎麼測試,隻是配起來用了下,機器差不多的話感覺就是輪詢。

===============================

cd nginx-0.7.67; 

patch -p0 < ../nginx_upstream_hash-0.3.1/nginx.patch 

configure時: 

./configure --prefix=/app/nginx -user=nobody -group=nobody \ 

--add-module=../nginx_upstream_hash-0.3.1/ \ 

--add-module=../gnosek-nginx-upstream-fair-2131c73/

========================================

upstream  www.test1.com {

          ip_hash;

          server   172.16.125.76:8066 weight=10;

          server   172.16.125.76:8077 down;

          server   172.16.0.18:8066 max_fails=3 fail_timeout=30s;

}

繼續閱讀