Nginx學習總結

2017年2月23日, 星期四

Nginx學習總結

   Nginx是目前比較主流的HTTP反向代理服務器(其企業版提供了基於TCP層的反向代理插件),對於構建大型分佈式web應用,具備舉足輕重的做用。簡單來講,nginx有2個主要的功能:動/靜態資源分離、負載均衡。javascript

 

    動/靜態資源分離:nginx支持正則表達式以區分靜態資源或者動態資源,其中動態資源能夠進一步轉發給後端的proxy server,而靜態資源則能夠在nginx層面使用本地緩存策略或者重定向(類CDN)到其餘nginx上。css

    負載均衡:對於動態資源而言,若是有多個proxy server,那麼nginx將會根據必定的算法選擇合適的server,並轉發請求,最終將客戶端request相對均衡的分發給多個server。html

 

    Nginx做爲「單點」,面向客戶端請求,並將請求轉發給後端的某個server,由於server能夠有多個,那麼從總體而言,提高了站點的「資源整合」能力,提高了站點的總體吞吐能力;但由於受限於nginx自己的IO模型,並無「下降」對物理資源的消耗(即性能開支);一般nginx做爲整個站點的「避雷針」和導流通道,它應該被架設在物理資源較爲優越的機器上,好比8U物理機,32核心,64G內存,對磁盤要求相對較低,對CPU、內存、網卡帶寬有較高的要求,由於nginx不只須要和客戶端請求創建連接,並且還須要與後端proxy server創建連接而且負責流量輸入、輸出(這和LVS、Haproxy有本質區別),這種雙倍的連接創建,就要求機器具備較高的內存和CPU,若是你的nginx還有大量的「靜態資源」cache,還須要使用高速、高容量的磁盤。由於nginx節點最終爲全部proxy server流量的總和,那麼它應該具備更高的網卡帶寬。前端

 

    爲了不資源競爭,應該避免nginx和web server部署在同一個節點上,由於web server一般爲CPU和內存高耗型,這會大大下降nginx的代理能力java

    1) 在中小型應用中(PV在KW級別,單一垂直web應用),一般一個nginx代理多個(組)server便可。node

    2)對於大中型應用,一個nginx將沒法支撐所有的流量,咱們將會採用多個nginx代理(複製了1)中的架構模型),並在nginx前端繼續構建高性能的分流設備,好比LVS、Haproxy等更低層的軟/硬件負載均衡器,這種負載均衡器一般只是「轉發」,而不涉及到流量的輸出,因此轉發效率將會更高,承載能力更強。linux

    3)不管什麼時候,咱們也不但願nginx存在單點故障問題,那麼一般咱們還須要使用keepalived(其餘同類型技術,VIP)來提升nginx節點的可用性,即Master-backup模式。nginx

    4)當有多個nginx時,爲了提高後端server的代理能力,一般還會讓多個nginx之間交叉重疊代理後端的server。git



 

1、經常使用模塊github

    在nginx 中,有幾個經常使用的模塊(module):

  • ngx_http_core_module:核心模塊;內置模塊。
  • ngx_http_upstream_module:「upstream」模塊,內置模塊,核心模塊;用於請求的「負載均衡」。
  • ngx_http_proxy_module:「請求代理」模塊,核心模塊;將請求轉發給代理Server,或者對請求進行額外的cache操做。
  • ngx_http_rewrite_module:「URL重寫」模塊,內置模塊;根據規則,rewrite特定的URL並轉發給代理Server。
  • ngx_http_access_module:「訪問控制」模塊;「容許」或者「拒絕」特定的IP列表對server的訪問,內置模塊。
  • ngx_http_limit_conn_module:「訪問控制」模塊;能夠限定每一個key(能夠爲客戶端IP)容許的最大併發鏈接數,內置模塊。
  • ngx_http_limit_req_module:「訪問控制」模塊;能夠限定每一個key(能夠爲客戶端IP)在單位之間內容許處理的request個數,「流量控制」,內置模塊。
  • ngx_http_headers_module:「header」模塊;主要是「add_header」和「expired」兩個指令,向response中添加header信息,內置模塊。
  • ngx_http_charset_module:「字符集」模塊;在響應頭部的「Content-Type」中增長charset信息,內置模塊。
  • ngx_http_addition_module:「增添」模塊;在response內容以前或者以後額外添加文本信息,內置模塊。
  • ngx_http_sub_module:「後置修改響應」模塊;能夠過濾並替換response內容中特定的字符串,附加模塊,須要在編譯時指定「--with-http_sub_module」。
  • ngx_http_fastcgi_module:將請求發送給「fastcgi」服務器,內置模塊。
  • ngx_http_geo_module:「geo」模塊;建立一個變量,此變量的值由client ip值決定,對實現小型私有「CDN」方案有參考價值,內置模塊
  • ngx_http_geoip_module:「geo」模塊;經過配置(數據源)能夠得知client ip所屬的「城市」、「區域」等信息,對實現小型私有的CDN有必定的參考價值,附加模塊,須要在編譯時指定「--with-http_geoip_module」。
  • ngx_http_gzip_module:「gzip」模塊;對response使用gzip壓縮,對減小數據傳輸量有益,內置模塊。
  • ngx_http_gzip_static_module:「gzip」模塊;對response使用gzip壓縮,輸出爲「.gz」文件,附加模塊,須要在編譯時指定「--with-http_gzip_static_module」。
  • ngx_http_image_filter_module:「圖片」模塊;能夠對「JPEG」、「GIF」、「PNG」格式的圖片進行裁剪等操做,附加模塊,須要在編譯時指定「--with-http_image_filter_module」。
  • ngx_http_status_module/ngx_http_stub_status_module:「nginx內部狀態」模塊;用於獲取nginx內部的一些狀態統計信息,一般用來獲取一些簡單的統計數據,其中nginx_http_stub_status_module爲附加模塊,編譯時須要指定「--with-http_stub_status_module」。
  • nginx-http-concat:第三方附加模塊,由taobao開發,主要用於合併「靜態資源」請求,提高性能,須要額外下載,並在編譯時添加「--add-module=/root/software/nginx-http-concat-master」。
  • ngx_cache_purge:第三方附件模塊,由frickle提供,當在proxy中使用cache保存靜態資源時,那麼cache_purge模塊提供刪除過時數據的功能支持,須要額外下載,並在編譯時添加「--add-module=/root/software/ngx_cache_purge」。

2、安裝(mac下)

    接下來,咱們就嘗試安裝nginx,從官網下載最新版1.8.0壓縮包,並按照以下步驟一次安裝,本人所使用的平臺爲mac OS(很遺憾,mac下安裝這些軟件,仍是至關的費勁)。爲了方便起見,咱們將上述經常使用的module一次性所有安裝或者加載(避免之後從新增長module帶來的麻煩)。下文中所下載的軟件都先保存到/usr/local/src下。

    一、下載ngx_cache_purge模塊:http://labs.frickle.com/nginx_ngx_cache_purge/,解壓後保存在本地目錄。

    二、下載ngx-http-concat模塊:https://github.com/alibaba/nginx-http-concat,解壓後保存在本地目錄。

    三、下載nginx並解壓,保存在/usr/local/src,重命名爲「nginx-1.8.0-src」。

    四、configure操做,經過--prefix指定nginx最終的可執行文件copy到哪一個目錄,這個目錄不須要提早建立。

 

Java代碼   收藏代碼
  1. ##進入nginx目錄  
  2. ./configure --prefix=/usr/local/nginx-1.8.0 --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --add-module=/usr/local/src/nginx-http-concat-master --add-module=/usr/local/src/ngx_cache_purge/  
  3.    

 

   極有可能你會獲得一個錯誤「./configure: error: the HTTP rewrite module requires the PCRE library.」,這意味着若是須要安裝rewrite模塊,那麼就須要安裝PCRE包(perl正則表達式)。

Java代碼   收藏代碼
  1. ##mac系統,linux下都可使用此編譯安裝的方式  
  2. ##首先下載pcre包:http://www.pcre.org/,解壓  
  3. ##進入解壓包  
  4. sudo ./configure --prefix=/usr/local  
  5. sudo make  
  6. sudo make install  

 

    而後你還會獲得一個錯誤「./configure: error: the HTTP image filter module requires the GD library.」,GD包主要用於圖形處理,這個須要手動安裝。安裝GD以前,須要依次安裝libpng、libjpeg,freetype,zlib(mac下不須要安裝,默認已經有了)。

Java代碼   收藏代碼
  1. ##libpng,在sourceforge.net上搜索「libpng」,下載tar.xz文件,解壓,並執行以下命令  
  2. sudo ./configure --prefix=/usr/local  
  3. sudo make  
  4. sudo make install  

 

Java代碼   收藏代碼
  1. ##libjpeg,在http://www.ijg.org/files目錄下,下載jpegsrc.v9a.tar.gz(或者下載最新的壓縮包,不要下載源文件版)   
  2. sudo ./configure --prefix=/usr/local  
  3. sudo make  
  4. sudo make install  

 

Java代碼   收藏代碼
  1. ##freetype,在sourceforge.net上搜索「freetype」,下載tar.bz2文件,並解壓。  
  2. sudo ./configure --prefix=/usr/local  
  3. sudo make  
  4. sudo make install  

 

Java代碼   收藏代碼
  1. ##libgd:https://bitbucket.org/libgd/gd-libgd/downloads,下載tar.xz格式文件,若是你知道如何編譯,也能夠在libgd.org下載源碼。  
  2. sudo ./configure --prefix=/usr/local --with-jpeg=/usr/local --with-png=/usr/local --with-freetype=/usr/local  
  3. sudo make  
  4. sudo make install  

 

    在安裝libgd時,必須指定jpeg,png,freetype這些lib的位置,不然此後在nginx安裝時會報錯:

Java代碼   收藏代碼
  1. Undefined symbols for architecture x86_64:  
  2.   "_gdImageCreateFromPngPtr", referenced from:  
  3.       _ngx_http_image_resize in ngx_http_image_filter_module.o  
  4.   "_gdImagePngPtr", referenced from:  
  5.       _ngx_http_image_resize in ngx_http_image_filter_module.o  
  6. ld: symbol(s) not found for architecture x86_64  

 

    上述lib安裝完畢以後,而後再次運行3)中的nginx的configure指令,應該就沒有錯誤,而後依次執行「make」 「make install」,此後咱們會在「/usr/local/nginx-1.8.0」目錄下看到相關的可執行文件、配置文件等。若是確實安裝成功,那麼咱們此前的「nginx-1.8.0-src」便可刪除,此後的操做只須要在安裝後的文件中進行便可。

    五、測試運行

    進入sbin目錄,執行「./nginx」,啓動nginx,若是出錯,請到logs目錄下查看緣由。而後在瀏覽器中輸入「127.0.0.1」(無需端口),你將會獲得nginx的歡迎頁。

    接下來,咱們將依次介紹nginx的幾個經常使用的模塊,在認識如何配置nginx的同時,簡單瞭解nginx的工做原理。

 

    咱們能夠經過「./nginx -V」查看nginx的configure信息。

    「./nginx -t」用於檢測配置文件是否合法。

    「./nginx -s stop」:關閉。

    「./nginx -s quit」:優雅關閉。

    「./nginx -s reopen」:從新打開log文件

    「./nginx -s reload」:從新加載配置信息,咱們在修改了conf文件以後,一般使用reload便可直接加載,無需重啓nginx。

 

    nginx會啓動一個master進程,和「worker_processes」個worker進程,其中master進程主要的做用就是「加載、評定配置信息」、「維護worker進程」,worker進程用於處理實際的request,nginx基於平臺的event模型,向worker進程分發request。    

 

    當master進程收到reload信號時,首先檢測配置文件的合法性,而後嘗試使用新的配置信息;若是成功,master將啓動新的worker進程,並向原來的worker進程發消息請求他們shutdown,此後request將會被抓發給新的worker進程,對於原來的worker將本身已經accept的請求處理完以後即關閉;若是配置文件有問題,master將會回滾配置的更改,而worker進程不受任何影響。

 

    六、配置文件樣例

Java代碼   收藏代碼
  1. #user  nobody;  
  2. worker_processes  2;  
  3. worker_rlimit_core 256m;  
  4. worker_rlimit_nofile 65535;  
  5.   
  6. error_log  logs/error.log  info;  
  7.   
  8. #pid        logs/nginx.pid;  
  9.   
  10. daemon on;  
  11. worker_priority 0;  
  12.   
  13. events {  
  14.     #use epoll;  
  15.     use kqueue;#linux 請使用epoll  
  16.     accept_mutex on;  
  17.     accept_mutex_delay 500ms;  
  18.     worker_connections  65535;  
  19. }  
  20.   
  21.   
  22. http {  
  23.     include       mime.types;  
  24.     default_type  application/octet-stream;  
  25.   
  26.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
  27.                       '$status $body_bytes_sent "$http_referer" '  
  28.                       '"$http_user_agent" "$http_x_forwarded_for"';  
  29.   
  30.     sendfile        on;  
  31.     #tcp_nopush     on;  
  32.     keepalive_timeout  65;  
  33.   
  34.     server {  
  35.         listen       80;  
  36.         server_name  localhost;  
  37.         access_log  logs/localhost.access.log  main;  
  38.   
  39.         location / {  
  40.             root   html;  
  41.             index  index.html index.htm;  
  42.         }  
  43.   
  44.         error_page  404              /404.html;  
  45.         error_page   500 502 503 504  /50x.html;  
  46.         location = /50x.html {  
  47.             root   html;  
  48.         }  
  49.   
  50.     include vhosts/*.conf;  
  51. }  

 

    上面的配置信息應該是最基本的,基本上nginx可以對靜態頁面作代理,下文中全部的模塊都基於這個配置模板。

 

3、代理簡析

    nginx一個重要的能力就是靜態文件的代理(或cache),包括html、images等,這些靜態文件一般放置在本地,好比:/data/www(一些html文件,css,js等),/data/images(圖片文件)。

Java代碼   收藏代碼
  1. location / {  
  2.     root   html;  
  3.     #index  index.html index.htm;  
  4. }  
  5.   
  6. location /images {  
  7.     root /data;  
  8. }  

 

    root」表示文件所在的本地路徑,最終請求的uri將會被添加到root路徑以後,造成完整的文件路徑,好比「127.0.0.1/images/header.jpg」,其uri爲「images/header.jpg」,那麼最終將會訪問本地的「/data/images/header.jpg」(若是本地文件沒有訪問權限,將會拋出「Permission denied」)。此處還涉及到location的匹配優先級的問題,就像「/images/header.jpg」對於location爲「/」和「/images」都匹配,在這種狀況下,nginx將會選擇「最長前綴」的哪個,即「/images」;此外,location還能支持正則表達式,因此匹配的規則將會比較複雜,咱們稍後詳解location。

 

    對於動態代理,須要配置一個(或一組,經過upstream模塊支持)web server,nginx接收客戶端請求(能夠對header進行修改),而後傳遞給web server,並等待接收proxy server的響應內容,而後再把response發送給客戶端(能夠對response的內容或者header進行修改),在此過程當中,nginx須要與客戶端、web server均要創建連接,nginx就像一個「轉發橋」,只是負責將請求,根據location或者其餘規則,匹配到一個合適的web server上。

 

Java代碼   收藏代碼
  1. server {  
  2.     listen 80 default_server;  
  3.     server_name localhost;  
  4.     location / {  
  5.         proxy_pass http://127.0.0.1:8080;  
  6.     }  
  7. }  

 

    proxy_pass將請求轉發給web server,不過這個指令還有更多的意義,咱們稍後詳解upstream、proxy模塊。動態代理,即實際處理請求(響應數據的server)的server在運行時經過必定的算法計算獲得的,並且還能夠根據請求的參數特徵來修改response的內容;一般咱們會指定多個web server,根據必定的「負載均衡」算法選取其中一個負責處理實際的請求。

 

    「server_name」這個指令很是有用,nginx一般根據http請求header中的「Host」字段與「server_name」列表匹配,斷定使用哪一個「server」配置,而後根據uri匹配location,斷定將次request交給哪一個web server處理。關於server_name的匹配規則,還須要必定的瞭解。(以下部分配置樣例中省略了部分無關的信息)

Java代碼   收藏代碼
  1. server {  
  2.     listen 80;  
  3.     server_name example.org www.example.org;  
  4. }  
  5. server {  
  6.     listen 80;  
  7.     server_name *.example.org;  
  8. }  
  9. server {  
  10.     listen 80;  
  11.     server_name mail.*;  
  12. }  
  13. server {  
  14.     listen 80;  
  15.     server_name ~^(?<name>.+)\.example\.net$;  
  16. }  

  

    對於指定的請求,nginx從header中host值,將按照以下順序進行匹配:

    1)精確的全限定名:好比server_name爲「www.exmaple.org」,「example.org」。

    2)以「*」開頭的最長的通配名稱:好比server_name爲「*.exmaple.org」。

    3)以「*」結束的最長的通配名稱:好比server_name爲「mail.*」。

    4)首個匹配的正則表達式。nginx中正則表達式以「~」或者「~*」開頭,咱們稍後詳解nginx的正則格式。

 

    注意,在nginx中,通配表達式和正則表達式被認爲是不一樣的,通配表達式必須以「*」開頭或者結束,且「*」不能在字符串的中間出現,好比「www.*.example.org」是不合法的;不然應該在正則表達式中使用「*」,好比「~^w.*\.exmaple\.org$」,注意若是在正則表達式中使用字符串「.」,應該須要轉義爲「\.」,不然「.」是被做爲正則表達式中特殊模式(即匹配任意字符串);通配表達式,「*」能夠匹配任意多個部分,好比「*.example.org」能夠匹配「www.exmaple.org」、「www.sub.exmaple.org」;那麼對於「.example.org」這種格式被認爲是一種特殊的正則表達式,它能夠匹配「exmaple.org」、「*.example.org」。

    上文中提到,nginx中正則表達式必須以「~」開頭(或者~*開頭,表示字符大小寫敏感)、「^」、「$」結尾,這三個特殊符號構成nginx(或者說是PCRE)正則表達式,不然被認爲是普通的「全限定名」。若是你瞭解過正則表達式,其實這些仍是很是容易理解的,不過若是正則表達式中包括「{」、「}」表示匹配次數區間,那麼整個表達式都須要用引號包含,不然會編譯錯誤。

Java代碼   收藏代碼
  1. server_name "~^(?<name>\w\d{1,3}+)\.example\.net$"  

 

    正則表達式中可使用"?<name>"這種格式,在PCRE中稱爲「命名捕獲」(named captures),那麼「name」能夠做爲當前context中的一個變量使用。在nginx中還可使用「數字」類型的命名捕獲。

Java代碼   收藏代碼
  1. ##參數方式  
  2. server {  
  3.     server_name ~^(www\.)?(?<domain>.+)$;  
  4.     location / {  
  5.          root /sites/$domain;  
  6.     }  
  7. }  
  8.   
  9. ##數字方式,效果等同  
  10. server {  
  11.     server_name ~^(www\.)?(.+)$;  
  12.     location / {  
  13.         root /sites/$2;  
  14.     }  
  15. }  

 

    咱們還須要對待那些特殊的狀況,好比請求的header中沒有「Host」或者爲空,那麼能夠用一個空字符串來匹配這種請求:

Java代碼   收藏代碼
  1. server {  
  2.     server_name example.org www.example.org "" 192.168.1.1;  
  3. }  

 

    固然有些時候,咱們還會使用IP去訪問一個nginx(沒有配置host解析,一般在測試環境),那麼咱們咱們請求的「Host」就是一個IP字符串,那麼咱們仍然能夠按照這種規則配置server_name。

Java代碼   收藏代碼
  1. server {  
  2.     listen 80 default_server;  
  3.     server_name _;  
  4. }  

 

    如上述例子所示,「default_server」表示爲若是沒有任何匹配的server_name時,將選擇此server來處理。其中server_name若是配置爲「_」,則表示此server匹配全部的「Host」,這些Host僅爲那些不能經過「精確全限定名」、「通配表達式」、「正則表達式」匹配的。

    根據server偵聽的端口號,將會把「精確匹配」、「以*開頭的通配表達式」、「以*結尾的通配表達式」保存在三個hashtable中(cache),這個hashtable的大小能夠經過配置文件調整;針對一個host,將會首先使用「精確匹配」,若是沒有找到相應的server_name,將會從「以*開頭的通配表達式」中查找,而後再從「已*結尾的通配表達式」中查找;從「通配表達式」的hashtable中查找,要慢於「精確匹配」,不過對於「.example.org」這種格式會被保存在「通配表達式」的hashtable中,而不是保存在「精確匹配」的hashtable中。對於「正則表達式」時最慢的一種方式,也是最後參與匹配的,將會根據它們在配置文件中的順序,依次去匹配。基於這些緣由,比較好的辦法就是儘量的使用「精確全限定名」,好比:

Java代碼   收藏代碼
  1. server {  
  2.     server_name example.org www.example.org *.example.org;  
  3. }  
  4. server {  
  5.     server_name sub.example.org;  
  6. }  

 

    而不是像這樣簡單的配置:

 

Java代碼   收藏代碼
  1. server {  
  2.     server_name .example.org;  
  3. }  

 

    若是你定義了較多的server配置或者較長的server_name字符串,那麼就須要經過「server_names_hash_max_size」(會影響server_name的個數)、「server_names_hash_bucket_size」(影響server_name的字符串長度)來調整配置,不然會拋出錯誤,咱們不須要貿然去調整這兩個參數,直到它出錯。

 

4、負載均衡

    使用nginx,其實還對其「負載均衡」的特性比較看重。一般咱們有多個web server對等部署,nginx將會經過「負載均衡」模塊將請求轉發給合適的web server,最終提高了web站點的總體吞吐能力,同時也提升了可用性。須要注意,nginx目前是Http層面的負載均衡器,在1.9V以後將提供TCP層面的負載均衡支持。以下爲nginx內置的負載均衡算法

    1)round-robin:輪詢,request將會依次有序的分發給web server。one by one!默認使用此算法。

    2)least-connected:最小鏈接數,請求將會被分發給當前連接數最小的server。配置名「least_conn」。

    3)ip-hash:根據請求的客戶端IP做爲hashing key,來斷定選擇哪一個server。配置名「ip_hash」。

 

Java代碼   收藏代碼
  1. http {  
  2.     upstream backend {  
  3.         ##least_conn;  
  4.         server 192.168.1.110 weight=3;  
  5.         server 192.168.1.120;  
  6.     }  
  7.     server {  
  8.         listen 80 default_server;  
  9.         #  
  10.         server_name _;  
  11.         location / {  
  12.             proxy_pass http://backend;  
  13.         }  
  14.     }  
  15. }  

 

    上述配置,就是一個簡單的「負載均衡」的樣例,首先在一個「upstream」區塊中聲明server列表,而後在proxy_pass指令中使用它;若是沒有聲明「負載均衡」算法,那麼默認就是用「round-robin」,其餘可選值爲「least_conn」、「ip_hash」,「負載均衡」算法須要在upstream區塊的首行聲明。

    「least_conn」算法可讓全局的性能開支,在多個server之間趨於平衡,由於不一樣的server可能在物理性能上就有差距,並且不一樣的request處理耗時也不盡相同;若是但願處理比較快的server可以儘量的接收更多的請求,那些負載較高的server也能穩步推動(後續咱們會提到流量控制),那麼「least_conn」算法將很是適合。一般咱們在production環境中,均採用此算法。

 

    「least_conn」和「round-robin」算法,將會把一個客戶端(來自同一個IP)的請求分發給不一樣的server上,這在某些狀況下並不妥,好比「粘性session」,同一個客戶端的請求應該被轉發給同一個server(除非此server失效後,纔會被轉發到其餘server),不然session會話中的數據將會丟失。那麼「ip_hash」算法將比較適合。不過基於殘酷的現實,粘性session的設計方案並不通用。

    可以影響負載均衡策略的還有一個重要的參數:權重;「權重」用來標記某個server承載請求的「優先級」,一般權重越高的server將優先得到客戶端請求,事實上「權重」也是表示一個server「承載」能力的大小,咱們一般能夠對硬件配置較高的server給予較高的權重,這有點像粗顆粒的「虛擬化」,若是一個server的硬件配置是另外一個的2倍,那麼能夠將權重值設置爲其2倍。

    默認upstream中全部的server權重都同樣,那麼「負載均衡」算法將平等對待它們。

 

Java代碼   收藏代碼
  1. upstream backend {  
  2.     server 192.168.1.110 weight=3 max_fails=3 fail_timeout=10s;  
  3.     server 192.168.1.120;  
  4.     server 192.168.1.130;  
  5. }  

 

    對於上述配置,每5個請求,將有3個分發給「192.168.1.110」,其餘兩個server各一個。上述提到的三種負載均衡算法中,均可以使用weight。

 

    「健康監測」對於負載均衡是必須的,這是提供可用性、「故障遷移」的必要手段。好比當某個server失效,請求未能正常處理,那麼咱們應該將分發給那些「正常」的server,並將故障的server從列表中移除,直到它恢復,以免後續更多的請求處理失敗。nginx當與一個server創建連接失敗後,會在「fail_timeout」時間內最多嘗試「max_fails」次,若是仍爲失敗,則將次server標記爲「failed」,並從服務列表中移除。默認「max_fails」爲1,若是「max_fails」爲0,則表示關閉「健康檢測」;「fail_timeout」(默認位10s)表示檢測多久後被標記爲「failed」,nginx會以優雅的方式檢測那些失效的server,若是它們再次上線,則將它們標記爲「alive」,便可繼續提供服務。

 

    更多的關於「負載均衡」配置方式,咱們將在下文「upstream」模塊中詳解。

 

5、計量單位

    nginx配置文件中,對於表示「數據尺寸」的數字後,能夠跟上「k」、「m」、「g」等單位縮寫字母,無單位後綴表示「字節」。對於表示「時間」的數字,可使用「ms」、「s」、「m」(分鐘)、h、d(天)、w(周)、M(月)、y(年),咱們還能以組合的方式使用它們,好比「1h 30m」,表示一小時30分鐘,至關於「90m」或者「5400s」,無單位後綴表示「秒」。以下例:

 

Java代碼   收藏代碼
  1. proxy_cache_path  /home/proxy_cache_path levels=1:2 keys_zone=cache_one:64m inactive=1d max_size=30g;  

    

6、HTTPS配置

    https忽然風靡起來,就連小論壇也開始用https,顯的很技術派,彷佛它的低性能的缺點並無想象的那麼可怕。在實際環境中,nginx和後端的web server都可以支持htps,爲了架構的簡單性,以及不但願web協議干擾程序的實現,咱們一般在nginx這一次支持https,而在web server層(好比tomcat)則繼續使用http協議。配置樣例以下:

Java代碼   收藏代碼
  1. upstream backend  
  2.  {  
  3.     server   192.168.1.110:8080;  
  4.     server   192.168.1.120:8080;  
  5.  }  
  6. server {  
  7.     listen 80;  
  8.     server_name www.example.com example.com;  
  9.     rewrite ^/(.*)$  https://$host/$1 last;  
  10.  }  
  11.    
  12. server {  
  13.     listen 443;  
  14.     server_name www.example.com example.com;  
  15.     ssl on;  
  16.     ssl_certificate      /usr/local/nginx/conf/ssl/example.com_bundle.crt;  
  17.     ssl_certificate_key  /usr/local/nginx/conf/ssl/example.com.key;  
  18.     ssl_session_cache shared:SSL:10m;  
  19.     ssl_session_timeout  5m;  
  20.     keepalive_timeout 60;  
  21.     ssl_protocols  SSLv3 TLSv1 TLSv1.2 TLSv1.1;  
  22.     ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;  
  23.     ssl_prefer_server_ciphers   on;  
  24.   
  25.     location / {  
  26.         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;  
  27.         proxy_pass http://backend;  
  28.     }  
  29. }  

    不管如何,你在使用HTTPS以前,須要開啓SSL,若是是線上應用,還須要從第三方機構購買一個合法的認證包(若是本身生成,其實並無什麼卵用),這個包裏將會包含crt和key兩個文件,而後根據上述nginx樣例將文件的路徑配置正確便可,須要提醒,nginx須要有訪問這兩個文件的權限。

 

    SSL操做須要消耗額外的CPU資源,主要在SSL握手階段,有2種方式能夠減小每一個客戶端的這種操做:1)開啓連接的keepalive選項(http 1.1),那麼一個客戶端能夠經過一個(次)連接發送多個請求,事實上達成了連接重用的目的,減小了建立連接和「握手」的次數。 2)重用SSL session參數,以免此後的子連接再進行握手操做,經過「ssl_session_cache」配置,session將會被保存在cache中,能夠在workers進程之間共享,1M的cache空間能夠保存大概4000個sessions,緩存生命週期默認爲5分鐘,能夠經過「ssl_session_cache」修改。「ssl_session_cache shared:SSL:10m」表示cache能夠在多個workers進程之間共享,cache名位「SSL」,緩存大小爲10M(數據尺寸,不是10分鐘)。

 

    上述配置,任何http請求都會被rewrite成https,不過在proxy_pass分發給後端web server時使用http協議,這是一種比較經常使用的方式,因此讓你的網站支持https,只須要在nginx層作認證便可,不須要調整web server的配置。

 

7、其餘

    在描述nginx的指令以前,咱們基本熟悉了nginx指令的配置方式:「<指令名稱> 值 [可選參數名=參數值];」,以「;」結束,一個區塊咱們能夠包含多個指令,那麼這種區塊稱爲context(上線文),nginx中經常使用的區塊有「http」、「events」、「server」、「upstream」、「location」等,最外層的context稱之爲「main」,context一般是有繼承關係,好比「location」須要包含在「server」中。「#」表示行註釋。 

    在nginx配置文件中,若是配置項表示路徑,好比「root /data/images」,若是爲相對路徑,則起始與nginx根目錄。

    一個指令能夠被配置在多個context下,好比「root」:

Java代碼   收藏代碼
  1. http {  
  2.     root /data/www;  
  3.     server {  
  4.         listen 80;  
  5.         server_name localhost;  
  6.         root /data/www/html;  
  7.         location / {  
  8.               root html;  
  9.              index index.html index.htm;  
  10.         }  
  11.     }  
  12. }  

    那麼根據context的繼承關係,子context的指令將覆蓋其父context,同理,其餘指令也將是如此。

 

8、nginx常規配置模板

Java代碼   收藏代碼
  1. #user  www www;  
  2. worker_processes auto;  
  3. error_log  /home/wwwlogs/nginx_error.log crit;  
  4. #pid        /usr/local/nginx/nginx.pid;  
  5.   
  6. #Specifies the value for maximum file descriptors that can be opened by this process.  
  7. worker_rlimit_nofile 655350;  
  8.   
  9. events  
  10.     {  
  11.         use epoll;  
  12.         worker_connections 655350;  
  13.     }  
  14.   
  15. http  
  16.     {  
  17.         include       mime.types;  
  18.         default_type  application/octet-stream;  
  19.   
  20.         server_names_hash_bucket_size 128;  
  21.         client_header_buffer_size 32k;  
  22.         large_client_header_buffers 4 32k;  
  23.         client_max_body_size 50m;  
  24.         server_tokens off;  
  25.   
  26.         sendfile on;  
  27.         tcp_nopush     on;  
  28.   
  29.         keepalive_timeout 60;  
  30.   
  31.         tcp_nodelay on;  
  32.   
  33.         fastcgi_connect_timeout 300;  
  34.         fastcgi_send_timeout 300;  
  35.         fastcgi_read_timeout 300;  
  36.         fastcgi_buffer_size 64k;  
  37.         fastcgi_buffers 4 64k;  
  38.         fastcgi_busy_buffers_size 128k;  
  39.         fastcgi_temp_file_write_size 256k;  
  40.         proxy_connect_timeout 600;  
  41.         proxy_read_timeout 600;  
  42.         proxy_send_timeout 600;  
  43.         proxy_buffer_size 64k;  
  44.         proxy_buffers   4 32k;  
  45.         proxy_busy_buffers_size 64k;  
  46.         proxy_temp_file_write_size 64k;  
  47.           
  48.         gzip on;  
  49.         gzip_min_length  1k;  
  50.         gzip_buffers     4 16k;  
  51.         gzip_http_version 1.0;  
  52.         gzip_comp_level 2;  
  53.         gzip_types   text/plain application/x-javascript text/css application/xml text/xml application/json;  
  54.         gzip_vary on;  
  55.         log_format  access '$remote_addr - $remote_user [$time_local] $host '  
  56.                                    '"$request" $status $body_bytes_sent $request_time '  
  57.                                    '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"'  
  58.                                    '$upstream_addr $upstream_status $upstream_response_time' ;  
  59.         server {  
  60.             listen 80;  
  61.             server_name  _;  
  62.             return 403;  
  63.         }  
  64.         include vhost/*.conf;  
  65. }  

    以「exmaple.org」爲例,以下爲基於upstream負載均衡模式的配置:

Java代碼   收藏代碼
  1. upstream example_backend {  
  2.           server   127.0.0.1:9080;  
  3.           server   192.168.1.198:9080;  
  4.  }  
  5. server {  
  6.         listen 80;  
  7.         server_name www.example.org example.com .example.org;  
  8.       
  9.     location / {  
  10.         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;  
  11.         proxy_pass http://example_backend;  
  12.         proxy_http_version 1.1;  
  13.         proxy_set_header Host $host;  
  14.         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  15.     }  
  16.     access_log  logs/www.example.org.log;  
  17.     location ~ .*\.(gif|jpg|jpeg|png|bmp|ico|swf|xml|css|js)$ {  
  18.         proxy_pass      http://example_backend;  
  19.         proxy_set_header        Host    $host;  
  20.         proxy_set_header        X-Real-IP       $remote_addr;  
  21.         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;  
  22.         expires 15d;  
  23.     }  
  24.     location ~ .*\.(jhtml)$ {  
  25.         proxy_pass      http://example_backend;  
  26.         proxy_set_header        Host    $host;  
  27.         proxy_set_header        X-Real-IP       $remote_addr;  
  28.         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;  
  29.         expires -1;  
  30.     }  
  31. }  

    上述配置中,對後端web server返回的靜態類型文件,讓瀏覽器緩存15天,對於jhtml格式的動態文件不緩存。

9、基於HTTPS配置核心配置

Java代碼   收藏代碼
  1. upstream example_backend {  
  2.     server   127.0.0.1:9080;  
  3.     server   192.168.1.198:9080;  
  4.  }  
  5. server {  
  6.         listen 80;  
  7.         server_name www.example.org example.org;  
  8.         rewrite ^/(.*)$  https://$host/$1 last;  
  9.  }  
  10. server {  
  11.     listen 443;  
  12.     server_name www.example.org example.org;  
  13.   
  14.     ssl on;  
  15.     ssl_certificate      /usr/local/nginx/conf/ssl/example.crt;  
  16.     ssl_certificate_key  /usr/local/nginx/conf/ssl/example.key;  
  17.     ssl_session_timeout  5m;  
  18.     ssl_protocols  SSLv3 TLSv1 TLSv1.2 TLSv1.1;  
  19.     ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;  
  20.     ssl_prefer_server_ciphers   on;  
  21.   
  22.     location / {  
  23.         ...  
  24.     }  
  25. }  

 

10、對於文件系統而言,基於nginx緩存的配置

Java代碼   收藏代碼
  1. upstream static_backend {  
  2.     server 192.168.1.198:8080;  
  3.     server 127.0.0.1:8080;  
  4. }  
  5. #設置Web緩存區名稱爲cache_one,內存緩存空間大小爲256MB,1天沒有被訪問的內容自動清除,硬盤緩存空間大小爲30GB。  
  6. proxy_temp_path   /home/proxy_temp_dir;  
  7. proxy_cache_path  /home/proxy_cache_path levels=1:2 keys_zone=cache_one:256m inactive=1d max_size=30g;  
  8.   
  9. server {  
  10.     listen       80;  
  11.     server_name static.example.org;  
  12.     location / {  
  13.             proxy_next_upstream http_502 http_504 error timeout invalid_header;  
  14.             proxy_cache cache_one;#nginx本地cache開啓  
  15.             proxy_cache_valid 200 304 30d;  
  16.             proxy_cache_valid 301 302 404 1m;  
  17.             proxy_cache_valid any 1m;  
  18.             proxy_cache_key $host$request_uri;  
  19.   
  20.         add_header X-Proxy-Cache $upstream_cache_status;  
  21.             proxy_set_header  Host $host;  
  22.             proxy_set_header  X-Real-IP  $remote_addr;  
  23.             proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;  
  24.             proxy_set_header X-Forwarded-For $remote_addr;  
  25.             proxy_set_header If-Modified-Since $http_if_modified_since;  
  26.   
  27.         expires 30d;#客戶端緩存,在header中增長「Expires」  
  28.         add_header Cache-Control public;  
  29.         proxy_pass http://static_backend;  
  30.             if_modified_since before;  
  31.         }  
  32.     #location ~ /purge(/.*) {  
  33.         # allow 127.0.0.1;  
  34.         # allow 192.168.1.0/24;  
  35.         # deny  all;  
  36.         # proxy_cache_purge cache_one $host$1$is_args$args;  
  37.     # }  
  38.     #https://github.com/FRiCKLE/ngx_cache_purge/  
  39.     access_log  /home/wwwlogs/static.example.org.log  access;  
  40. }  

 

 



相關文章
相關標籤/搜索