負載均衡集羣解決方案 (二)Nginx

Nginx是一個免費的,開源的,高性能的服務器和反向代理服務器軟件,同時它也能夠爲IMAP和POP3服務器代理,以其高性能,穩定性,豐富的功能,結構簡單,低資源消耗的特性換來廣大運維者所喜好。javascript

Nginx與傳統的服務器不一樣,不依賴線程來處理請求。相反,它使用一個更可擴展事件驅動架構(異步)。這種結構資源消耗較小,但更重要的是,能夠承受較大的請求負荷。即便你不但願處理成千上萬的請求,你仍然能夠受益於Nginx的高性能和小的內存佔用,以及其豐富的功能。php

Nginx的反向代理:css

反向代理指以代理服務器來接受Internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給Internet上請求鏈接到客戶端,此時代理服務器對外就表現爲一個服務器,而此種工做模式相似於LVS-NET模型。前端

反向代理也能夠理解爲web服務器加速,它是一種經過在繁忙的web服務器和外部網絡之間增長的 一個高速web緩衝服務器,用來下降實際的web服務器的負載的一種技術。反向代理是針對web服務器提升加速功能,全部外部網絡要訪問服務器時的全部請求都要經過它,這樣反向代理服務器負責接收客戶端的請求,而後到源服務器上獲取內容,把內容返回給用戶,並把內容保存在本地,以便往後再收到一樣的信息請求時,它會將本地緩存裏的內容直接發給用戶,已減小後端web服務器的壓力,提升響應速度。所以Nginx還具備緩存功能。java

反向代理的工做流程:nginx

1)用戶經過域名發出訪問請求,該域名被解析爲反向代理服務器的IP地址;git

2)反向代理服務器接收用戶的請求;github

3)反向代理服務器在本地緩存查找是否存在當前用戶所請求的內容,找到則直接把內容返回給用戶;web

4)若是本地沒有用戶請求的內容,反向代理服務器會以本身的身份去後端服務器請求一樣的信息內容,並把信息內容發給用戶,若是信息內容是能夠被緩存的,則會將該內容緩存在代理服務器的本地緩存中。正則表達式

反向代理的好處:

1)解決了網站服務器對外可見的問題,提升了網站服務器的安全性;

2)節約了有限的IP地址資源,後端服務器都可使用私有IP地址與代理服務器進行通訊;

3)加速了網站的訪問速度,減輕了真是web服務器的負荷。

(一)、調度算法

Nginx的upstream指令用於指定proxy_pass和fastcgi_pass所使用的後端服務器,即nginx的反向代理功能,所以能夠將二者結合起來使用以達到負載均衡的目的,而Nginx也支持多種調度算法:

一、輪詢(默認)

每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,則會跳過該服務器分配至下一個監控的服務器。而且它無需記錄當前全部鏈接的狀態,因此它是一種無狀態調度。

二、weight

指定在輪詢的基礎上加上權重,weight和訪問比率成正比,即用於代表後端服務器的性能好壞,若後端服務器性能較好則可將大部分請求分配給它,已實現其力所能及。

例如:

我後端服務器172.23.136.148配置:E5520*2 CPU,8G內存

後端服務器172.23.136.148配置:Xeon(TM)2.80GHz * 2,4G內存

我但願在有30個請求到達前端時,其中20個請求交給172.23.136.148處理,剩餘10個請求交給172.23.136.149處理,就可作以下配置

upstream web_poll {

server 172.23.136.148 weight=10;

server 172.23.136.149 weight=5;

}

三、ip_hash

每一個請求按訪問ip的hash結果分配,當新的請求到達時,先將其客戶端IP經過哈希算法進行哈希出一個值,在隨後的請求客戶端IP的哈希值只要相同,就會被分配至同一個後端服務器,該調度算法能夠解決session的問題,但有時會致使分配不均即沒法保證負載均衡。

例如:

upstream web_pool {

ip_hash;

server 172.23.136.148:80;

server 172.23.136.149:80;

}

四、fair(第三方)

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

upstream web_pool {

server 172.23.136.148;

server 172.23.136.149;

fair;

}

五、url_hash(第三方)

按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。

例:在upstream中加入hash語句,server語句中不能寫入weight等其餘的參數,hash_method是使用的hash算法

upstream web_pool {

server squid1:3128;

server squid2:3128;

hash $request_uri;

hash_method crc32;

}

每一個設備的狀態設置爲:

1.down 表示當前的server不參與負載,用於ip_hash中

2.weight 默認爲1.weight越大,負載的權重就越大。

3.max_fails 容許請求失敗的次數默認爲1.設爲0則表示關閉該項功能,當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤

4.fail_timeout 在max_fails定義的失敗次數後,暫停的時間。

5.backup 能夠將其理解爲備機,其它全部的非backup機器down或者忙的時候,纔會將請求分配給backup機器。因此這臺機器壓力會最輕。

nginx支持同時設置多組的負載均衡,用來給不用的server來使用。

(二)、指令的使用

一、upstream

聲明一組能夠被proxy_pass和fastcgi_pass引用的服務器;這些服務器可使用不一樣的端口,而且也可使用Unix Socket;也能夠爲服務器指定不一樣的權重。如:

upstream web_pool {

    server coolinuz.9966.org weight=5;

    server 172.23.136.148:8080 max_fails=3  fail_timeout=30s;

    server unix:/tmp/backend3;

}

二、server

語法:server name [parameters]

其中的name能夠是FQDN,主機地址,端口或unix套接字;若是FQDN解析的結果爲多個地址,則每一個地址都會被用到。

三、proxy_pass

語法:proxy_pass URL;

該指令用於指定代理服務器的地址和URL將被映射爲的URL或地址和端口。即用來指定後端服務器的地址或URL[端口]。

四、proxy_set_header

語法:proxy_set_header header value;

該指令容許從新定義和添加一些將被轉移到被代理服務器的請求頭部信息。

例如:

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

注意:$proxy_add_x_forwarded_for包含客戶端請求頭中的"X-Forwarded-For",與$remote_addr用逗號分開,若是沒有"X-Forwarded-For" 請求頭,則$proxy_add_x_forwarded_for等於$remote_addr

順便補上Nginx的內置變量:

$args, 請求中的參數;

$is_args, 若是已經設置$args,則該變量的值爲「?」,不然爲「」。

$content_length, HTTP請求信息頭裏的"Content-Length";

$content_type, 請求信息頭裏的"Content-Type";

$document_root, 針對當前請求所屬的root指令設置的根目錄路徑;

$document_uri, 與$uri相同;

$host, 請求信息中的"Host",若是請求中沒有Host行,則等於設置的服務器名;

$limit_rate, 對鏈接速率的限制;

$request_method, 請求的方法,好比"GET"、"POST"等;

$remote_addr, 客戶端地址;

$remote_port, 客戶端端口號;

$remote_user, 客戶端用戶名,認證用;

$request_filename, 當前請求的文件路徑名

$request_body_file, 客戶端請求主體的臨時文件名。

$request_uri, 請求的URI,帶參數;

$query_string, 與$args相同;

$scheme, 所用的協議,好比http或者是https,好比rewrite  ^(.+)$ $scheme://example.com$1  redirect;

$server_protocol, 請求的協議版本,"HTTP/1.0"或"HTTP/1.1";

$server_addr, 服務器地址,若是沒有用listen指明服務器地址,使用這個變量將發起一次系統調用以取得地址(形成資源浪費);

$server_name, 請求到達的服務器名;

$server_port, 請求到達的服務器端口號;

$uri, 請求的URI,可能和最初的值有不一樣,好比通過重定向之類的。

五、proxy_read_timeout

語法:proxy_read_timeout time;

這個指令設置Nginx與後端服務器創建鏈接後。等待後端服務器的響應時間

六、proxy_send_timeout

語法:roxy_send_timeout time;

該指令指定請求轉移到後端服務器的超時時間。整個傳輸的要求時間不超過超時時間,但只有兩次寫操做之間。若是在此時間以後的後端服務器將不採起新的數據,而後nginx將關閉鏈接。

七、proxy_connect_timeout

語法:proxy_connect_timeout time;

該指令用來設置分配到後端服務器的鏈接超時時間。

八、proxy_buffers

語法: proxy_buffers the_number is_size;

該指令設置緩衝區的數目和大小,缺省狀況下,一個緩衝區的大小和頁面大小相同。

九、proxy_buffer_size

語法:proxy_buffer_size buffer_size;

代理緩衝區,該指令用於保存用用戶的頭部信息。

十、proxy_busy_buffers_size

語法:proxy_busy_buffers_size size;

用於當系統負載較大,緩衝區不夠用時,能夠申請更大的proxy_buffers

十一、proxy_temp_file_write_size

語法:proxy_temp_file_write_size size;

用於指定緩存臨時文件的大小

(三)、功能完善

安裝配置第三方模塊,實現upstream中對後端web server的健康狀態檢測:

模塊下載地址:https://github.com/cep21/healthcheck_nginx_upstreams;模塊名稱:ngx_http_healthcheck_module

安裝配置方法:

一、首先解壓healcheck模塊到某路徑下,這裏假設爲/tmp/healthcheck_nginx_upstreams

#tar -xvf cep21-healthcheck_nginx_upstreams-16d6ae7.tar.gz -C /tmp/healthcheck_nginx_upstreams

二、對nginx打補丁

首先解壓nginx,並進入nginx源碼目錄:

# tar xf nginx-1.3.4.tar.gz

# cd nginx-1.0.11

# patch -p1 < /tmp/healthcheck_nginx_upstreams/nginx.patch

然後編譯nginx,在執行configure時添加相似下面的選項:

--add-module=/tmp/healthcheck_nginx_upstreams

因此,這裏就使用以下命令:

# ./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--lock-path=/var/lock/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--http-proxy-temp-path=/var/tmp/nginx/proxy/ \
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
--with-pcre \
--add-module=/tmp/healthcheck_nginx_upstreams
# make && make install

ngx_http_healthcheck_module模塊的使用方法:

一、此模塊支持的指令有:

healthcheck_enabled ##啓用此模塊

healthcheck_delay ##對同一臺後端服務器兩次檢測之間的時間間隔,單位毫秒,默認爲1000;

healthcheck_timeout ##進行一次健康檢測的超時時間,單位爲毫秒,默認值2000;

healthcheck_failcount ##對一臺後端服務器檢測成功或失敗多少次以後方纔肯定其爲成功或失敗,並實現啓用或禁用此服務器;

healthcheck_send ##爲了檢測後端服務器的健康狀態所發送的檢測請求;如:healthcheck_send "GET /health HTTP/1.0" 'Host: coolinuz.9966.org';

healthcheck_expected ##指望從後端服務器收到的響應內容;若是未設置,則表示從後端服務器收到200狀態碼即爲正確;

healthcheck_buffer ##健康狀態檢查所使用的buffer空間大小;

healthcheck_status

經過相似stub_status的方式輸出檢測信息,使用方法以下:

location /stat {

  healthcheck_status;

}

(四)、配置與實現

配置代碼以下:

http {
  upstream web_pool {
    server 172.23.136.148:80 weight=10;
    server 172.23.136.149:80 weight=5;
    healthcheck_enabled;
    healthcheck_delay 1000;
    healthcheck_timeout 1000;
    healthcheck_failcount 2;
    healthcheck_send "GET /.health HTTP/1.0";
  }
  server {
    listen 80;
    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://web_pool;
      proxy_connect_timeout 3;
    }
    location /stat {
      healthcheck_status;
    }
  }
}

在這裏設置「proxy_set_header」參數,是由於Nginx在作反向代理的時候,要代替客戶端去訪問服務器,因此,當請求包通過反向代理後,在代理服務器這裏這個IP數據包的IP包頭作了修改,最終後端web服務器獲得的數據包的頭部的源IP地址是代理服務器的IP地址,這樣一來,後端服務器的程序給予IP的統計功能就沒有任何意義,或者後端web服務器上有多個基於域名的虛擬主機時,就要經過添加Header頭信息Host,用於指定請求的域名,這樣後端web服務器才能識別該反向代理訪問請求由哪一個虛擬主機來處理。

(五)、小結

經過以上咱們能夠看出Nginx的配置實際上是比較其餘的web服務器軟件是比較簡單的,可是其實現的功能確實至關強大豐富的。經過Nginx的反向代理已經支持靈活的正則表達式匹配,能夠實現網站的動、靜分離,讓動態的php等程序網頁去訪問php web服務器,讓緩存頁、圖片、javascript、css、flash去訪問Squid等緩存服務器或文件服務器。加之Nginx對靜態內容的高性能,高併發量,Nginx做爲前端代理負載均衡成爲愈來愈多架構師的首先方案。

本文出自 「My---Dream.*」 博客,請務必保留此出處http://grass51.blog.51cto.com/4356355/1109825

相關文章
相關標籤/搜索