架構設計:負載均衡層設計方案(3)——Nginx進階

上篇文章《架構設計:負載均衡層設計方案(2)——Nginx安裝》(http://blog.csdn.net/yinwenjie/article/details/46620711),咱們介紹了Nginx的核心設計思想、基本安裝和使用。原本準備繼續介紹Nginx的幾個使用特性,可是奈何博文篇幅太長,只有將一篇文章拆成兩篇。本文咱們將承接上文,繼續講解Nginx的實用特性,包括gzip功能、rewirte功能和一個第三方的節點監測模塊。本文咱們還將提到Taobao團隊對Nginx的深度改造Tengine。javascript

一、Nginx繼續進階

1.一、gzip

nginx對返回給瀏覽器的http response body是能夠進行壓縮的。雖然須要消耗一點cpu和內存資源,可是想到100KB的數據量能夠壓縮到60KB甚至更小進行傳輸,是否有必定的吸引力?這裏個人建議是,不要爲了節約成本將業務服務和負載層服務放在一臺物理服務器上,這樣作既影響性能又增長了運維難度。http返回數據進行壓縮的功能在不少場景下都實用:css

  • 若是瀏覽器使用的是3G/4G網絡,那麼流量對於用戶來講就是money。java

  • 壓縮可節約服務器機房的對外帶寬,爲更多用戶服務。按照目前的市場價良好的機房帶寬資源的通常在200RMB/Mbps,而服務器方案的壓力每每也來自於機房帶寬。mysql

  • 主要注意的是,不是Nginx開啓了gzip功能,HTTP響應的數據就必定會被壓縮,除了知足Nginx設置的「須要壓縮的http格式」之外,客戶端(瀏覽器)也須要支持gzip(否則它怎麼解壓呢),一個好消息是,目前大多數瀏覽器和API都支持http壓縮。linux

    咱們首先來說解Nginx中的gzip的設置參數,而後咱們講解當開啓壓縮功能後,HTTP的交互過程和過程當中關鍵的幾個屬性。咱們首先來看看Nginx中開啓gzip的屬性(gzip的設置放置在HTTP主配置區域):nginx

    #開啓gzip壓縮服務,
    gzip on;git

    #gzip壓縮是要申請臨時內存空間的,假設前提是壓縮後大小是小於等於壓縮前的。例如,若是原始文件大小爲10K,那麼它超過了8K,因此分配的內存是8 * 2 = 16K;再例如,原始文件大小爲18K,很明顯16K也是不夠的,那麼按照 8 * 2 * 2 = 32K的大小申請內存。若是沒有設置,默認值是申請跟原始數據相同大小的內存空間去存儲gzip壓縮結果。
    gzip_buffers 2 8k;github

    #進行壓縮的原始文件的最小大小值,也就是說若是原始文件小於5K,那麼就不會進行壓縮了
    gzip_min_length 5K;web

    #gzip壓縮基於的http協議版本,默認就是HTTP 1.1
    gzip_http_version 1.1;正則表達式

    # gzip壓縮級別1-9,級別越高壓縮率越大,壓縮時間也就越長CPU越高
    gzip_comp_level 5;

    #須要進行gzip壓縮的Content-Type的Header的類型。建議js、text、css、xml、json都要進行壓縮;圖片就不必了,gif、jpge文件已經壓縮得很好了,就算再壓,效果也很差,並且還耗費cpu。
    gzip_types text/HTML text/plain application/x-javascript text/css application/xml;

    設置完成後,重啓nginx,便可生效。下面咱們來看看瀏覽器和服務器進行gzip壓縮的請求和處理返回過程(實際上在個人《標準Web系統的架構分層》文章中,已經有所說起):

這裏寫圖片描述

  • 整個請求過程來看,開啓gzip和不開啓gip功能,其http的請求和返回過程是一致的,不一樣的是參數。這個能夠看看個人另一篇文章《標準Web系統的架構分層》http://blog.csdn.net/yinwenjie/article/details/46480485

  • 當開啓HTTP的gzip功能時,客戶端發出http請求時,會經過headers中的Accept-Encoding屬性告訴服務器「我支持gzip解壓,解壓格式(算法)deflate,sdch爲:」。Accept-Encoding:gzip,deflate,sdch

  • 注意,不是request說本身支持解壓,Nginx返回response數據的時候就必定會壓縮。這還要看本次Nginx返回數據的格式是什麼,若是返回數據的原始數據格式,和設置的gzip_types相符合,這時Nginx纔會進行壓縮。

  • Nginx返回response headers是,若是數據被壓縮了,就會在Content-Encoding屬性中標示gzip,表示接下來返回的response content是通過壓縮的;而且在Content-Type屬性中表示數據的原始格式。

  • 最後返回通過壓縮的response content給客戶端,客戶端再進行解壓。這裏注意一下,在客戶端發送的headers裏面,有一個deflate,sdch。這是兩種壓縮算法,若是讀者感興趣,能夠查查相關的資料(我建議查查,瞭解哈弗曼壓縮算法對擴展本身的架構思路頗有幫助)

1.二、rewrite

本小結內容,假定讀者瞭解正則表達式。若是您不清楚正則表達式,請首先Google或者百度,正則表達式不在咱們討論的範圍內。

Nginx的強大在於其對URL請求的重寫(重定位)。Nginx的rewrite功能依賴於PCRE Lib,請必定在Nginx編譯安裝時,安裝Pcre lib。請參見個人上一篇文章《架構設計:負載均衡層設計方案(2)——Nginx安裝》http://blog.csdn.net/yinwenjie/article/details/46620711

咱們先從講解rewrite的關鍵語法,而後出示幾個示例,由示例進行講解。先來講一下Nginx中幾個關鍵的語法:

正在表達式匹配:

  • ~ 區分大小寫進行正則表達式匹配
  • ~* 不區分大小寫進行正則表達式匹配
  • !~ 區分大小寫進行正則表達式不匹配
  • !~* 不區分大小寫進行正則表達式不匹配

舉例說明:

示例1:location ~* \.(jpg|gif|png|ioc|jpeg)$

location是Nginx中的關鍵字,表明當前的URL請求值。
以上表達式表示對URL進行不區分大小寫的匹配,一旦URL以jpg或gif或png或ioc或jpeg結尾時,匹配成功。

示例2:$var1 ~ ^(\d+)$

var1是Nginx中使用set關鍵字定義的變量,以上語句表明var1和一個整數進行匹配。

Nginx中的全局變量:
從上面的各個實例中,咱們已經發現Nginx是支持變量的,Nginx還內置了一些全局變量,這裏列舉一些比較重要的全局變量:

  • $content_length: 獲取request中header部分的「Content_Length」值。
  • $content_type: 獲取request中header部分的「Content_type」值。
  • $request_method: 請求方式,經常使用的有兩種請求方式:POST、GET
  • $remote_addr: 發送請求的客戶端ip
  • $remote_port: 發送請求的客戶端端口
  • $request_uri: 含有參數的完整的初始URI
  • $server_addr: request到達的server的ip。
  • $server_port: 請求到達的服務器的端口號。

rewrite語法

rewrite regex replacement flag

#regex:表示當前匹配的正則表達式。只有$url大小寫相關匹配regex正則表達式,這個$url纔會被rewrite進行重定向。

#replacement:重定向目標規則。這個目標規則支持動態變量綁定,這個問題下文立刻用示例來說。

#flag:重定向規則。

rewrite中的Flag關鍵字

  • redirect:通知客戶端重定向到rewrtie後面的地址。
  • permanent:通知客戶端永久重定向到rewrtie後面的地址。
  • last:將rewrite後的地址從新在server標籤執行。
  • break:將rewrite後地址從新在當前的location標籤執行。

實際上針對客戶端來講,其效果是同樣的,都是由客戶端從新發起http請求,請求地址從新定位到replacement規則的URL地址;這裏關鍵要講解最經常使用的last和break兩個關鍵字:

全部的rewrite語句都是要在server中的location中書寫的,以下:
server {
    。。。。。。
    。。。。。。
    location ... {
        if(...) {
            rewirte regex replacement flag;
        }
        rewirte regex replacement flag;
    }
}

那麼,break關鍵字說明重寫的replacement地址在當前location的區域立刻執行。
last關鍵字說明重寫的replacement地址在當前server全部的location中從新再作匹配。

下面咱們結合rewrite關鍵字和rewrite flag關鍵字給出典型的示例進行講解:

示例1:
location ~* ^/(.+)/(.+)\.(jpg|gif|png|jpeg)$ {
    rewrite ^/orderinfo/(.+)\.(jpg|gif|png|jpeg)$   /img/$1.$2   break;
    root   /cephclient;
}

location在不進行大小寫區分的狀況下利用正則表達式對$url進行匹配。當匹配成功後進行rewrite重定位。
rewrite進行重寫url的規則是:regex表達式第一個括號中的內容對應$1,regex表達式第二個括號中的內容對應$2,以此類推。
這樣重定位的意義就很明確了:將任何目錄下的文件名重定位到img目錄下的對應文件名,
而且立刻在這個location中(注意是Nginx,而不是客戶端)執行這個重寫後的URL定位。


示例2:
server {
    。。。。
    。。。。
    location ~* ^/orderinfo/(.+)\.(jpg|gif|png|jpeg)$ {
        rewrite ^/orderinfo/(.+)\.(.+)$  /img/$1.$2   last;
    }

    location / {
        root   /cephclient;
    }
}

在server中,有兩個location位置,當url須要訪問orderinfo目錄下的某一個圖片時,rewrite將重寫這個url,
而且從新帶入這個url到server執行,這樣「location /」這個location就會執行了,並找到圖片存儲的目錄。

1.三、健康檢查模塊

在本小節咱們介紹一個用於Nginx對後端UpStream集羣節點健康狀態檢查的第三方模塊:nginx_upstream_check_module(https://github.com/yaoweibin/nginx_upstream_check_module)。這個模塊有資料介紹是TaoBao團隊開發的,可是我在GitHua上試圖求證時並無找到直接證據。

這裏須要說明的是,目前有不少Nginx模塊實現Nginx對後端集羣節點的健康監測,不止nginx_upstream_check_module。Nginx官方有一個模塊healthcheck_nginx_upstreams也能夠實現對後端節點的健康監測(https://github.com/cep21/healthcheck_nginx_upstreams有詳細的安裝和使用介紹)

咱們回到對nginx_upstream_check_module的講解,要使用這個第三方模塊首先您須要進行下載,而後經過patch命令將補丁打入您原有的Nginx源碼中,而且從新進行編譯安裝。下面咱們來重點講解一下這個模塊的安裝和使用。

下載nginx_upstream_check_module模塊:

wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master

您也能夠直接到GitHua上進行下載,還一個在linux系統上使用git命令進行下載。

解壓安裝,並補丁打入Nginx源碼

# unzip ./nginx_upstream_check_module-master.zip

注意是將補丁打入Nginx源碼,不是Nginx的安裝路徑:

# cd ./nginx-1.6.2

# patch -p1 < ../nginx_upstream_check_module-master/check_1.5.12+.patch

若是補丁安裝成功,您將看到如下的提示信息:
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
patching file src/http/ngx_http_upstream_round_robin.h

這裏請注意:在nginx_upstream_check_module官網的安裝說明中,有一個打補丁的注意事項:
If you use nginx-1.2.1 or nginx-1.3.0, the nginx upstream round robin
module changed greatly. You should use the patch named
'check_1.2.1.patch'.
If you use nginx-1.2.2+ or nginx-1.3.1+, It added the upstream
least_conn module. You should use the patch named 'check_1.2.2+.patch'.
If you use nginx-1.2.6+ or nginx-1.3.9+, It adjusted the round robin
module. You should use the patch named 'check_1.2.6+.patch'.
If you use nginx-1.5.12+, You should use the patch named
'check_1.5.12+.patch'.
If you use nginx-1.7.2+, You should use the patch named
'check_1.7.2+.patch'.

這裏咱們的Nginx的版本是1.6.2,那麼就應該打入check_1.5.12+.patch這個補丁

從新編譯安裝Nginx:

注意從新編譯Nginx,要使用add-module參數將這個第三方模塊安裝進去:

# ./configure --prefix=/usr/nginx-1.6.2/ --add-module=../nginx_upstream_check_module-master/

# make && make install

經過以上的步驟,第三方的nginx_upstream_check_module模塊就在Nginx中準備好了。接下來咱們講解一下如何使用這個模塊。首先看一下upstream的配置信息:

upstream cluster {
    # simple round-robin
    server 192.168.0.1:80;
    server 192.168.0.2:80;

    check interval=5000 rise=1 fall=3 timeout=4000;

    #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;
    #check interval=3000 rise=2 fall=5 timeout=1000 type=http;
    #check_http_send "HEAD / HTTP/1.0\r\n\r\n";
    #check_http_expect_alive http_2xx http_3xx;
}

上面的代碼中,check部分就是調用nginx_upstream_check_module模塊的語法:

check interval=milliseconds [fall=count] [rise=count]
[timeout=milliseconds] [default_down=true|false]
[type=tcp|http|ssl_hello|mysql|ajp|fastcgi]

interval:必要參數,檢查請求的間隔時間。

fall:當檢查失敗次數超過了fall,這個服務節點就變成down狀態。

rise:當檢查成功的次數超過了rise,這個服務節點又會變成up狀態。

timeout:請求超時時間,超過等待時間後,此次檢查就算失敗。

default_down:後端服務器的初始狀態。默認狀況下,檢查功能在Nginx啓動的時候將會把全部後端節點的狀態置爲down,檢查成功後,在置爲up。

type:這是檢查通訊的協議類型,默認爲http。以上類型是檢查功能所支持的全部協議類型。

check_http_send http_packet

http_packet的默認格式爲:"GET / HTTP/1.0\r\n\r\n"

check_http_send設置,這個設置描述了檢查模塊在每次檢查時,向後端節點發送什麼樣的信息

check_http_expect_alive [ http_2xx | http_3xx | http_4xx | http_5xx ]

這些狀態代碼表示服務器的HTTP響應上是OK的,後端節點是可用的。默認狀況的設置是:http_2xx | http_3xx

當您根據您的配置要求完成檢查模塊的配置後,請首先使用nginx -t 命令監測配置文件是否可用,而後在用nginx -s reload重啓nginx。

1.四、不得不提的tengine

Tengine是由淘寶網發起的Web服務器項目。它在Nginx的基礎上,針對大訪問量網站的需求,添加了不少高級功能和特性。Tengine的性能和穩定性已經在大型的網站如淘寶網,天貓商城等獲得了很好的檢驗。它的最終目標是打造一個高效、穩定、安全、易用的Web平臺(http://tengine.taobao.org/)。

您應該懂了,我建議您根據業務的實際狀況,適時在生產環境引入Tengine。但在本博客發佈時,Tengine的2.X版本還不穩定,因此建議實用1.5.2的穩定版本。請記住Tengine就是通過升讀改造後的Nginx

二、後文介紹

花了兩篇文章的功夫,終於將我想給你們講解的nginx的實用特性講完了,可是nginx遠遠不止這些特性。後面有時間咱們會再回到Nginx,重點講解針對Nginx的腳本開發,咱們還會講解Nginx和Lua的集成。可是爲了避免擾亂這個系列博文的時間安排,下篇文章咱們將開始介紹LVS技術,爭取用一篇文章的篇幅講清楚LVS核心設計思想、單節點安裝和使用。再下篇文章咱們介紹Keepalived技術,以及keepalived和LVS、Nginx分別進行集成,敬請關注。

相關文章
相關標籤/搜索