上篇文章《架構設計:負載均衡層設計方案(2)——Nginx安裝》(http://blog.csdn.net/yinwenjie/article/details/46620711),咱們介紹了Nginx的核心設計思想、基本安裝和使用。原本準備繼續介紹Nginx的幾個使用特性,可是奈何博文篇幅太長,只有將一篇文章拆成兩篇。本文咱們將承接上文,繼續講解Nginx的實用特性,包括gzip功能、rewirte功能和一個第三方的節點監測模塊。本文咱們還將提到Taobao團隊對Nginx的深度改造Tengine。javascript
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。這是兩種壓縮算法,若是讀者感興趣,能夠查查相關的資料(我建議查查,瞭解哈弗曼壓縮算法對擴展本身的架構思路頗有幫助)
本小結內容,假定讀者瞭解正則表達式。若是您不清楚正則表達式,請首先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還內置了一些全局變量,這裏列舉一些比較重要的全局變量:
rewrite語法
rewrite regex replacement flag #regex:表示當前匹配的正則表達式。只有$url大小寫相關匹配regex正則表達式,這個$url纔會被rewrite進行重定向。 #replacement:重定向目標規則。這個目標規則支持動態變量綁定,這個問題下文立刻用示例來說。 #flag:重定向規則。
rewrite中的Flag關鍵字
實際上針對客戶端來講,其效果是同樣的,都是由客戶端從新發起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就會執行了,並找到圖片存儲的目錄。
在本小節咱們介紹一個用於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。
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分別進行集成,敬請關注。