nginx 負載均衡之 ngx_http_upstream_hash_module

nginx的upstream模塊可以定義後端負載集羣,負載的分配方式也有好幾種,比如 ip_hash,RR,weight,url_hash,fair等。如果後端集羣session不共享的話,ip_hash,RR,weight,fair等負載均衡方式都將不適用,唯一可用的就是url_hash了。

要用url_hash需要安裝第三方模塊ngx_http_upstream_hash_module 。安裝以及配置方法點擊超鏈接即可。我這裏主要介紹如何利用ngx_http_upstream_hash_module對session不共享的集羣如何做負載均衡。

upstream的配置如下:

upstream pool1 {
hash 
$cookie_jsessionid;
server server1:80;
server server2:80;
server server3:80;
hash_again 1;
}

爲了保障同一個用戶始終分配到同一個後端服務器,我們需要找到能唯一標示用戶的標誌,毫無疑問,非sessionid莫屬了哈哈。因爲服務器端也是根據sessionid區分唯一用戶的。所以我們hash用的變量是 $cookie_jsessionid 。那麼hash_again是什麼意思呢?顧名思義hash_again就是再做一次hash的意思,那麼什麼情況下再做一次hash呢?爲什麼要再做一次hash呢?我們配上access_log來看看nginx都做了些什麼。

access_log格式配置如下:

log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘
‘”
$upstream_addr” “$upstream_cache_status” “$upstream_status” “$upstream_response_time” “$cookie_jsessionid“‘;

我們主要看upstream_addr、upsteam_status和cookie_jsessionid

首先我們訪問下index.jsp,日誌如下:

123.127.98.133 – - [02/Jul/2011:19:31:42 +0800] “GET /reg/register.jsp HTTP/1.1″ 200 14540  “Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1″ “-”"server1:80” “-” “200” “0.017″ “-

此時訪問的是server1 sessionid居然爲空!其實也可以理解第一次訪問時確實木有sessionid,因爲sessionid是服務器端生成後寫到瀏覽器的cookie 裏的,所以第一次訪問肯定沒有sessionid了。這樣一來,我們可以推測所有用戶的第一次請求都是發給同一臺後端服務器的。這樣的話如果恰好宕機的是負責處理第一次用戶的請求的服務器的話,那麼所有的新訪問的用戶都將無法訪問。

F5刷新頁面:

123.127.98.133 – - [02/Jul/2011:19:31:46 +0800] “GET http://abc.efg.com/index.jsp” 200 8920  “Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1″ “-”"server2:80” “-” “200” “0.002″ “abcC8pjNRr3jGbAWKNQdt

有sessionid了,而且請求被重新分配到了server2了,而且之後用戶所有的操作都分配到了server2。這個時候我們停掉server2,再次F5刷新頁面。日誌出如下:

123.127.98.133 – - [02/Jul/2011:19:33:08 +0800] “GET http://abc.efg.com/index.jsp” 200 14540 ” “Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1″ “-”"server2:80, server1:80” “-” “502, 200” “0.002, 0.015″ “abcC8pjNRr3jGbAWKNQdt

此時雖然我們已經停掉了server2但是我們仍然可以打開頁面,爲嘛?!此時hash_again大發神威了,此時我們可以從日誌裏看到 server2返回502,server1返回200。也就是說nginx請求server2是發現,靠!server2掛了,於是基於原來得到的 hash值再次進行hash,從而將請求發往了另外一臺機器server1。之後所有的請求也都是這樣,先請求server2,server2不可用,重新hash,訪問server1。那麼hash_again=2時代表什麼了?如果按照我們的配置hash_again=1,那麼當server2和 server1都蛋掉,但是server3可用。用戶請求時仍然會無法訪問。如果我們改成hash_again=2,那麼nginx會進行兩次hash嘗試,嘗試訪問後端其他可以用的機器。也就是說hash_again的值越大,整個系統的可用性就越高。

 

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