Nginx系列教程之三:nginx 必知必會

書接上回,聊一聊nginx的必知必會!!!javascript


    前言:從該教程日後,涉及到nginx的功能將愈來愈生產化,所以某些測試必須是基於web架構平臺,因此在看本教程以前,建議先安裝好LNMP或者LAMP架構,以便測試驗證。其次該技術文檔的測試是基於前端nginx反向代理與後端LNMP架構來測試的,後端LNMP主要是提供測試的訪問頁面而已,重點仍是前端Nginx的設置php

測試環境:
前端代理:
OS:CentOS6.5x64
hostname:test1.lxm.com
ip:10.0.10.11
css

後端LNMP:
OS:CentOS6.5x64
hostname:test2.lxm.com
ip:10.0.10.12
html

注意:未作特別說明,則全部配置均在前端代理上進行配置前端

1.nginx信號機制,平滑重啓和平滑升級
 nginx自己提供了5種信號機制,經過該信號機制可以實現nginx的平滑重啓,平滑升級,日誌切割等功能。
nginx信號機制:
HUP:實現平滑重啓nginx,所謂平滑重啓就是不重啓nginx的master進程,關閉原有worker進程,打開新的worker進程,這個過程不會中斷用戶的請求
USR1:用於實現nginx日誌的切割,使用該信號能夠在不重啓nginx進程的狀況下,從新打開一個nginx日誌文件
USR2:用來平滑升級nginx的可執行文件
WINCH:用來從容關閉nginx的worker進程,使用可信號不會當即結束nginx的worker進程,而是當worker進程處理完全部的鏈接後在關閉worker進程
QUIT:用來關閉nginx的master進程,在升級nginx時,會等全部的worker進程都結束後,從容的關閉nginx的舊版master進程
java

1)平滑重啓:
#kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
除此以外還有一種方式也能夠達到平滑重啓的目的:
#service nginx reload  or /usr/local/nginx/sbin/nginx -s reload
nginx

驗證:
查看當前nginx的進程,並記住進程號
[root@test1 sbin]# ps aux | grep nginx
root      1244  0.0  0.1  22276   900 ?        Ss   13:44   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx     1246  0.0  0.2  22660  1504 ?        S    13:44   0:00 nginx: worker process
平滑重啓nginx:
[root@test1 sbin]# kill -HUP `cat /usr/local/nginx/logs/nginx.pid`
[root@test1 sbin]# ps aux | grep nginx
root      1244  0.0  0.4  22408  2292 ?        Ss   13:44   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx     1254  0.0  0.3  22796  1656 ?        S    13:48   0:00 nginx: worker process
[root@test1 sbin]# service nginx reload
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
Reloading nginx:                                           [  OK  ]
[root@test1 sbin]# ps aux | grep nginx
root      1244  0.0  0.4  22408  2304 ?        Ss   13:44   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx     1271  0.0  0.3  22804  1668 ?        S    13:48   0:00 nginx: worker process 
web

經過上面的對比,發現平滑重啓後,nginx的master進程都保持不變,而worker進程每次都在變化正則表達式


2)平滑升級
    nginx的平滑升級功能是nginx的一大優點,一般軟件在升級的時候都必然會致使重啓服務而中斷用戶的請求服務。而nginx的平滑升級卻能夠實現熱升級,在不中斷用戶請求服務的狀況下就
能夠完美實現版本的升級。
 其次:要知道所謂軟件的升級,一般升級的都是可執行文件,nginx也是同樣,升級的是nginx的可執行文件
升級過程:
查看nginx當前版本:
[root@test1 nginx-1.7.4]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.6.1
[root@test1 nginx-1.7.4]#
可知,目前使用的版本是nginx1.6的,而要升級的是nginx1.7.4的版本
算法

查看nginx編譯的參數:
[root@test1 nginx-1.7.4]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.6.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx/ --with-pcre --with-http_ssl_module --with-openssl=/root/soft/openssl-1.0.1i --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --http-client-body-temp-path=/usr/local/nginx/client_body_temp/ --http-proxy-temp-path=/usr/local/nginx/proxy_temp/ --http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp/ --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp/ --http-scgi-temp-path=/usr/local/nginx/scgi_temp/

由上面的信息可知nginx的編譯參數

開始編譯新版本的nginx:
[root@test1 nginx-1.7.4]# ./configure --prefix=/usr/local/nginx/ --with-pcre --with-http_ssl_module --with-openssl=/root/soft/openssl-1.0.1i --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --http-client-body-temp-path=/usr/local/nginx/client_body_temp/ --http-proxy-temp-path=/usr/local/nginx/proxy_temp/ --http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp/ --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp/ --http-scgi-temp-path=/usr/local/nginx/scgi_temp/

configure若沒有錯誤,顯示以下信息:
Configuration summary
  + using system PCRE library
  + using OpenSSL library: /root/soft/openssl-1.0.1i
  + md5: using OpenSSL library
  + sha1: using OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx/"
  nginx binary file: "/usr/local/nginx//sbin/nginx"
  nginx configuration prefix: "/usr/local/nginx//conf"
  nginx configuration file: "/usr/local/nginx//conf/nginx.conf"
  nginx pid file: "/usr/local/nginx//logs/nginx.pid"
  nginx error log file: "/usr/local/nginx//logs/error.log"
  nginx http access log file: "/usr/local/nginx//logs/access.log"
  nginx http client request body temporary files: "/usr/local/nginx/client_body_temp/"
  nginx http proxy temporary files: "/usr/local/nginx/proxy_temp/"
  nginx http fastcgi temporary files: "/usr/local/nginx/fastcgi_temp/"
  nginx http uwsgi temporary files: "/usr/local/nginx/uwsgi_temp/"
  nginx http scgi temporary files: "/usr/local/nginx/scgi_temp/"

[root@test1 nginx-1.7.4]# make 
//注意:這裏千萬不要make install ,由於make install會全新安裝nginx,而不是熱升級了。若是沒有什麼報錯,則說明make基本是成功了。接下來就是熱升級的關鍵部分了

備份舊的可執行文件爲nginx.old,拷貝新的可執行文件到/usr/local/nginx/sbin/目錄下
[root@test1 nginx-1.7.4]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
[root@test1 nginx-1.7.4]# cp objs/ng
nginx               nginx.8             ngx_auto_config.h   ngx_auto_headers.h  ngx_modules.c       ngx_modules.o      
[root@test1 nginx-1.7.4]# cp -p objs/nginx /usr/local/nginx/sbin/
[root@test1 nginx-1.7.4]# ls -l /usr/local/nginx/sbin
total 14544
-rwxr-xr-x. 1 root root 7515939 Aug 26 14:32 nginx
-rwxr-xr-x. 1 root root 7376337 Aug 21 16:03 nginx.old

測試新版的nginx可執行程序是否正常:
[root@test1 nginx-1.7.4]# cd /usr/local/nginx/sbin/
[root@test1 sbin]# ls
nginx  nginx.old
[root@test1 sbin]# ./nginx -t -c /usr/local/nginx/conf/nginx.conf
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@test1 sbin]#
如上信息所示,nginx執行文件正常

升級nginx可執行文件:
[root@test1 sbin]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
[root@test1 sbin]# ps aux | grep nginx
root      1244  0.0  0.4  22408  2316 ?        Ss   13:44   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16086  0.0  0.3  22796  1664 ?        S    14:49   0:00 nginx: worker process                                         
root     16094  0.0  0.5  22296  2728 ?        S    14:50   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16095  0.0  0.3  22676  1512 ?        S    14:50   0:00 nginx: worker process                                         
root     16100  0.0  0.1 103244   848 pts/1    S+   14:50   0:00 grep nginx
[root@test1 sbin]# ls -l /usr/local/nginx/logs/
total 92
-rw-r--r--. 1 root root  9064 Aug 25 10:47 access.log
-rw-r--r--. 1 root root 51603 Aug 26 14:50 error.log
-rw-r--r--. 1 root root 14158 Aug 25 10:47 host.access.log
-rw-r--r--. 1 root root     6 Aug 26 14:50 nginx.pid
-rw-r--r--. 1 root root     5 Aug 26 13:44 nginx.pid.oldbin

如上信息可見,系統中如今有兩個nginx的主進程和各自的worker進程,而nginx的pid號也有兩個,其中一個變成了nginx.pid.oldbin,這說明此時舊版nginx和新版nginx在共存。

查看80端口的請求鏈接:
[root@test1 sbin]#netstat -nultp | grep 80
因爲是實驗,沒法演示效果,在生產環境中,你能夠看到若是當前還有正在處理的請求,必定是舊版的nginx worker進程在處理,等處理完了,只剩下監聽狀態的時候就能夠從容關閉舊版nginx的worker進程,再也不處理請求

從容關閉worker進程:
[root@test1 sbin]# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
[root@test1 sbin]# ps aux | grep nginx
root      1244  0.0  0.4  22408  2316 ?        Ss   13:44   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
root     16094  0.0  0.5  22296  2728 ?        S    14:50   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16095  0.0  0.3  22676  1512 ?        S    14:50   0:00 nginx: worker process

由上面的信息可見,舊版的worker進程已經關閉。

從容關閉舊版的master進程:
[root@test1 sbin]# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
[root@test1 sbin]# ps aux | grep nginx
root     16094  0.0  0.5  22296  2728 ?        S    14:50   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16095  0.0  0.3  22676  1512 ?        S    14:50   0:00 nginx: worker process                                         
root     16112  0.0  0.1 103244   848 pts/1    S+   14:58   0:00 grep nginx
[root@test1 sbin]# ls -l /usr/local/nginx/logs/
total 88
-rw-r--r--. 1 root root  9064 Aug 25 10:47 access.log
-rw-r--r--. 1 root root 52115 Aug 26 14:58 error.log
-rw-r--r--. 1 root root 14158 Aug 25 10:47 host.access.log
-rw-r--r--. 1 root root     6 Aug 26 14:50 nginx.pid
[root@test1 sbin]#

由上面的對比可見,此時只剩下新版的nginx進程了,並且舊版的nginx的pid文件也自動消失了。。

查看nginx的版本號確認:
[root@test1 sbin]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.7.4
[root@test1 sbin]#
因而可知此時nginx的版本已經升級到1.7.4了。而在這個過程當中,從未中斷過用戶的請求。接下來,刪除舊的nginx的可執行文件便可


2.日誌配置以及日誌切割
 在生產環境中,日誌的收集分析也是很重的環節。對於一個web站點,經過日誌能夠基本的分析出pv,uv,ip以及流量等信息。爲了對日誌進行統一的管理,就必須事先設定好日誌的格式,
以及日誌的保存方式。

日誌配置:
 一般狀況下使用nginx的默認日誌配置便可,全部日誌段都是nginx的內置變量組成的,若是想擴展nginx的日誌,只須要添加你想要的變量便可。
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
關於日誌變量的分析,這裏不在贅述,能夠查看nginx配置文件分析一章

日誌切割:
 日積月累,日誌文件的大小會愈來愈大,爲了方便統計和管理,常見的是對日誌進行天天切割保存。
 
 nginx日誌切割的原理是利用其USR1的信號機制,該信號可使用nginx在不重啓的狀況下就打開一個新的日誌文件
測試;
[root@test1 nginx]# cd /usr/local/nginx/logs/    //切換到日誌目錄下
[root@test1 logs]# ls  //查看日誌文件
access.log  error.log  host.access.log  nginx.pid
[root@test1 logs]# pwd
/usr/local/nginx/logs
[root@test1 logs]# ps aux | grep nginx   //查看如今的nginx進程好,必定要記住
root     16188  0.0  0.1  22276   900 ?        Ss   15:12   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16190  0.0  0.3  22660  1844 ?        S    15:12   0:00 nginx: worker process                                         
root     16208  0.0  0.1 103244   844 pts/1    S+   15:22   0:00 grep nginx
[root@test1 logs]# mv access.log access.log.bak   //移動當前的日誌文件爲bak
[root@test1 logs]# kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`    //從新生成日誌文件
[root@test1 logs]# ls
access.log  access.log.bak  error.log  host.access.log  nginx.pid   //查看此時的日誌文件,發現既有bak文件也有新生產的access.log文件
[root@test1 logs]# ps aux | grep nginx      //查看此時的nginx進程號
root     16188  0.0  0.2  22276  1032 ?        Ss   15:12   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx    16190  0.0  0.3  22660  1856 ?        S    15:12   0:00 nginx: worker process                                         
root     16213  0.0  0.1 103244   844 pts/1    S+   15:23   0:00 grep nginx
[root@test1 logs]#

從上面的信息能夠看出,nginx先後的進程號沒有發生任何的變化,所以可知USR1該信號能夠在不從新nginx進程的狀況下,從新生成日誌文件


日誌切割計劃任務部署:
切割腳本:
#vim /root/shellscripts/lognginx.sh
#!/bin/bash
logPath=/usr/local/nginx/logs   //nginx日誌的路徑
logBackupPath=/root/logs   //nginx日誌備份的路徑
oldLog=access.log   //定義nginx的日誌名
newLog=access-`date +%F`.log    //定義nginx備份的日誌文件名
pidPath=/usr/local/nginx/logs/nginx.pid    //定義nginx的進程號文件
mv $logPath/$oldLog $logBackupPath/$newLog
kill -USR1 `cat $pidPath`  

計劃任務:
#vim /etc/crontab  //添加一條以下內容,天天的凌晨進行日誌切割
0 0 * * * root /root/shellscripts/lognginx.sh

#service crontab restart  //重啓守護進程

OK,到此nignx的日誌切割也完成了。        


3.關閉nginx版本號的顯示
 爲了增強服務器的安全,隱藏軟件版本也是其中的一個手段,默認狀況下訪問nginx出錯時,會提示錯誤,可是也會顯示nginx的版本號
測試;
http://10.0.10.11/index.html2  //在瀏覽器中隨便輸入一個不存在的url,此時nginx抱以下錯誤

 

wKioL1P9mAShbsPZAAEhvVhrb2I317.jpg


 

由上面的信息,能夠很直觀的看出服務器使用了nginx,而且版本號是1.6.1. 對於高級的***者,根據版本好就可能找出相關的漏洞,所以必需要隱藏版本號

 

設置;
 在nginx.conf配置文件的http{}段中,增長一條指令
 server_tokens off;
 
重啓nginx服務器,再次訪問:
wKiom1P9lu3gNwZMAAEab7r2qLU780.jpg

發現此時再次訪問,雖然報錯,可是已經沒有nginx的版本信息了。

若是nginx後php整合了,建議同時取消fastcgi.param中的nginx版本信息:
wKioL1P9mAWxqGEYAAQGd6DGRzw249.jpg

 

4.基於ip和http基本認證的權限配置
 nginx自己也提供了一系列的安全防禦功能,基本的有ip權限控制和用戶認證控制
 
基於ip的認證:
 基於ip的認證涉及到兩個指令:allow deny。allow表示容許訪問,deny表示不容許訪問
測試:
修改nginx.conf配置文件,在location /裏面添加deny 和allow指令
 location / {
            root   html;
            index  index.html index.htm;
            deny 10.0.10.12;   //決絕該ip訪問
            allow all;   //容許其餘全部的ip地址訪問
        }
注意;allow,deny的匹配順序是次序匹配,匹配到則結束

在10.0.10.12虛擬機上訪問:
wKiom1P9lu6QsFDQAAEaIYfTIYo213.jpg

能夠看到,訪問被拒絕。

在宿主機上進行訪問,此時發現能夠正常訪問,顯示以下內容:

 

wKioL1P9mOuAm0rMAAEFCK0ufoc609.jpg

基於用戶的認證:
 nginx能夠實現基本的用戶認證
測試:
修改nginx.conf配置文件,修改內容以下:
 location / {
            root   html;
            index  index.html index.htm;
   auth_basic "relam authentication";  //auth_basci就表示開啓用戶身份認證功能
   auth_basic_user_file /usr/local/nginx/htpasswd;
        }
  
建立htpasswd文件:

  wKiom1P9l9TxB5zDAACUcvo8tzg926.jpg

//注:這裏的htpasswd命令要藉助於http-tool軟件包,沒安裝得要安裝一下

測試:
http://10.0.10.11/

wKiom1P9mEChrTBtAAEakKKHKRg695.jpg

如上圖所示,填入用戶名和密碼,點擊肯定便可訪問。

 

wKioL1P9mViSaokTAAECL1Wa8eA566.jpg

 

5.nginx status查看
 nginx提供了基本狀態信息查看機制,該模塊默認沒有啓用,要想啓用該功能必須在編譯nginx的時候手動添加;--with-http_stub_status_module

配置:
修改nginx.conf配置文件,在server{}段中添加一個location
 wKiom1P9mEHCrSUhAACfb0pQi7Q595.jpg  
訪問:
wKioL1P9mVjgkGHwAAEBy2xhLrM357.jpg


Active connections:表示當前活躍的鏈接數,
第二行的三個數字表示分別表示:nginx總共接受了多少個鏈接,成功創建了多少個鏈接,總共處理了多少個請求數
最後一行的Reading表示Nginx讀取到客戶端Header信息數, Writing表示Nginx返回給客戶端的Header信息數,「Waiting」表示Nginx已經處理完,正在等候下一次請求指令時的駐留鏈接數

 

6.nginx 錯誤頁面的配置
 在客戶端的訪問過程當中,確定會出現這樣或那樣的錯誤,爲了使體驗更加的人性化,能夠根據須要設計本身的錯誤頁面,而後經過nginx中error_page選項來調用錯誤頁面
error_page:用來設置錯誤的狀態碼轉換到對應的錯誤頁面
格式;
error_page status_code  page;
可是光設置這個尚未用,還必須配置location來指定該頁面所在的路徑,才能正確的調用

測試案例;
 在尚未配置的狀況下,訪問一個不存在的頁面,會報 404 not found的錯誤

 

wKioL1P9meLS8lnsAAFGinBr6mo468.jpg

 


 

接下來配置nginx的404錯誤頁面:
wKioL1P9mizDdpXLAABKu_C-YLM750.jpg  
#echo "<h1>this is 404 error page</h1>" > /usr/local/nginx/html/404.html  
 
重啓nginx進程,而後再次使用:
http://10.0.10.11/index.html2 ,此時會顯示預先定義的錯誤頁面內容.

wKiom1P9mNKQUuYfAAEAIxxJoaY416.jpg

轉換流程:
 客戶端訪問頁面時,若是發生了一個404的錯誤,此時服務器端會自動將url地址轉換爲:
http://10.0.10.11/404.html 此時就匹配了location的設置,從/usr/local/nginx/html目錄下
查找404.html文件,將其中的內容返回給客戶端。。


7.nginx gzip的配置
 爲了加速頁面的響應速度,nginx提供了對靜態文本實現gzip的壓縮功能,也提供了帶寬的利用率。
注:nginx默認不支持gzip的功能,要想開啓該功能,必須在編譯安裝的時候手動添加--with-http_gzip_static_module來開啓該功能
 
gzip相關的配置:
gzip on;  開啓gzip壓縮
gzip_min_length 1k;  設置容許壓縮的頁面最小字節數,默認爲0,無論頁面多大都壓縮,建議設置成大於1k,要特別注意壓縮的最小單位限制
gzip_buffers 4 16k;   設置容許多大的內存空間來壓縮的緩存,默認值是申請與原始數據大小相同的空間來壓縮。
gzip_http_version 1.1; 設置識別http協議版本
gzip_comp_level 2;  用來指定gzip的壓縮比,1壓縮比最小,處理最快,9壓縮比最大,處理最慢,也比較消耗cpu
gzip_types text/plain application/x-javascript text/css application/xml; 用來指定壓縮的類型,不管是否指定,text/html類型老是會被壓縮。
gzip_vary on;  可讓前端的緩存服務器緩存通過GZIP壓縮的頁面,例如用squid緩存通過nginx壓縮的數據。

以上即爲gzip的經常使用設置,在這裏須要說明一下的是gzip_types,該選項指定了要壓縮文件的類型,若是你不知道,最好的辦法是經過瀏覽器的調試功能來獲取某類文件的類型。經過查看瀏覽器調試功能,開啓網絡調試,在頁面的響應頭中有一個Content-type的字段,該字段顯示的就是此類文本的類型

example:

wKioL1P9merxdM_nAAd9xeXoemA381.jpg

 

哈哈,圖片截大了,拉小有點變形了,不過仍是能看到的....


8.nginx 反向代理配置
 nginx反向代理功能使用的是nginx的proxy模塊,該模塊默認已經支持。
測試案例:
在後端服務器10.0.10.12上建立好測試頁面:index.html
#echo "<h1>this is a proxy test</h1>"  > /usr/local/nginx/html/index.html

配置前端nginx代理功能:
相關配置以下:
wKioL1P9merDdGM0AAJxWkrTeds631.jpg

 

#service nginx configtest //測試配置文件是否有錯誤
#service nginx restart //重啓nginx服務器

訪問測試:

 

wKiom1P9mf3TlPPwAADoP12yxeo938.jpg


 

能夠訪問此時頁面已經被代理到後端的服務器上了。到此一個簡單的反向代理功能就實現了,根據本身的須要,能夠實現各類反向代理功能,好比匹配某個特定的url進行代理等.


反向代理的優化:
如下內容能夠放在某個server{}段內,也能夠放在http{}段內,對全部的server都生效
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

相關選項含義:
proxy_set_header:設置由後端的服務器獲取用戶的主機名或者真實IP地址,以及代理者的真實IP地址。
proxy_connect_timeout:表示與後端服務器鏈接的超時時間,即發起握手等候響應的超時時間。
proxy_send_timeout:表示後端服務器的數據回傳時間,即在規定時間以內後端服務器必須傳完全部的數據,不然,Nginx將斷開這個鏈接。
proxy_read_timeout:設置Nginx從代理的後端服務器獲取信息的時間,表示鏈接創建成功後,Nginx等待後端服務器的響應時間,實際上是Nginx已經進入後端的排隊之中等候處理的時間。
proxy_buffer_size:設置緩衝區大小, 默認,該緩衝區大小等於指令proxy_buffers設置的大小。
proxy_buffers:設置緩衝區的數量和大小。nginx從代理的後端服務器獲取的響應信息,會放置到緩衝區。
proxy_busy_buffers_size:用於設置系統很忙時可使用的proxy_buffers大小,官方推薦的大小爲proxy_buffers*2。
proxy_temp_file_write_size:指定proxy緩存臨時文件的大小
proxy_next_upstream:該選項設置當客戶端訪問頁面時,若是後端服務器返回該選項後面設置的錯誤時,則自動將請求轉發到負載均衡中的下一臺服務器,實現故障轉移
  

接下來聊一聊upstream
upstream指令用來設置上游服務器,而且根據須要能夠設置一些策略:
樣例:
upstream backend {
ip_hash;  設置nginx的負載均衡方法。
server 192.168.12.133:80;
server 192.168.12.134:80 down;
server 192.168.12.135:8009 max_fails=3 fail_timeout=20s;
server 192.168.12.136:8080;
server 192.168.12.137:8080 backup;
}
Nginx的負載均衡模塊目前支持4種調度算法,下面進行分別介紹,其中後兩項屬於第三方的調度方法。
輪詢(默認)。每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端某臺服務器宕機,故障系統被自動剔除,使用戶訪問不受影響。
Weight。指定輪詢權值,Weight值越大,分配到的訪問機率越高,主要用於後端每一個服務器性能不均的狀況下。
ip_hash。每一個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,有效解決了動態網頁存在的session共享問題。

fair。比上面兩個更加智能的負載均衡算法。此種算法能夠依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx自己是不支持fair的,若是須要使用這種調度算法,必須下載Nginx的upstream_fair模塊。
url_hash。按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,能夠進一步提升後端緩存服務器的效率。Nginx自己是不支持url_hash的,若是須要使用這種調度算法,必須安裝Nginx 的hash軟件包。

在HTTP Upstream模塊中,能夠經過server指令指定後端服務器的IP地址和端口,同時還能夠設定每一個後端服務器在負載均衡調度中的狀態。經常使用的狀態有:
down,表示當前的server暫時不參與負載均衡。
backup,預留的備份機器。當其餘全部的非backup機器出現故障或者忙的時候,纔會請求backup機器,所以這臺機器的壓力最輕。
max_fails,容許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。
fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails能夠和fail_timeout一塊兒使用。

注意 當負載調度算法爲ip_hash時,後端服務器在負載均衡調度中的狀態不能是backup
  
測試upstream的某些功能:
1)測試默認的負載均衡
爲了測試實驗效果,在前端代理10.0.10.11主機上再裝一個httpd軟件,搭建一個本地的web站點
#yum -y install httpd
#vim /etc/httpd/conf/httpd.conf
修改內容:
Listen 8080   //修改其監聽端口爲8080,由於此時nginx的監聽端口爲80,不修改會衝突
#service httpd start   //啓動httpd服務
#echo "<h1>this is 10.0.10.11 website</h1>" > /var/www/html/index.html

配置完成後你能夠先用瀏覽器或者links測試一下http是否可以正常提供服務:
http://10.0.10.11:8080
links --dump http://10.0.10.11:8080


配置前端代理nginx:
修改配置文件的location /和upstreamd的配置使其達到測試的需求:
location / {
                proxy_redirect off;
                proxy_pass  
http://backend;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
        }
  
upstream  backend {
  server 10.0.10.11:8080;
        server 10.0.10.12:80;
        }
  
說明:將請求代理到後端服務器組backend,此時的backend中有兩臺服務器,採用的是默認的輪詢負載均衡規則

#service nginx configtest
#service nginx restart

建立測試頁面,以便區別:
10.0.10.12:
#echo "<h1>this is 10.0.10.12 website</h1>" > /usr/local/nginx/html/index.html

注意:這裏爲了測試效果,因此測試頁面的內容不同,真正在生產環境中,兩臺服務器的內容應該是一摸同樣的

測試:
第一次訪問:
wKioL1P9mxXjHzQeAADjqnq6VxY006.jpg


第二次訪問:
wKiom1P9mf6DFpzZAADaih4Fgpg558.jpg

由上面的信息可知,nginx能夠正常的切換。你在測試時能夠多刷新幾回查看效果。


2)測試ip_hash
 ip_hash的效果是對ip地址進行hash,同一個ip地址會發送到同一臺後端服務器,所以當設置了ip_hash以後,測試頁面時,同一個ip地址訪問不管怎麼刷新,頁面都不會變化。
配置nginx.conf文件:

upstream  backend {
  ip_hash;
  server 10.0.10.11:8080;
        server 10.0.10.12:80;
        }

#service nginx configtest
#service nginx restart

自行測試效果。。。。

3)測試backup的功能
 backup的功能是作冗餘備份來使用,默認狀況下backup主機是不參與負載均衡請求,當其餘主機都出現故障沒法響應時,backup纔會響應客戶端的請求
配置nginx.conf文件:
upstream  backend {
  server 10.0.10.11:8080;
        server 10.0.10.12:80 backup;
        }
注意:backup不能和ip_hash一塊兒使用

#service nginx configtest
#service nginx restart

測試: 
 屢次訪問頁面:
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.11 website
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.11 website
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.11 website
[root@test1 conf]#
由上面的信息發現,無論怎麼訪問,返回的都是同一個頁面

此時,中止10.0.10.11上的站點:
wKioL1P9mxazQxikAAFqrFdW_6s580.jpg

再次訪問:
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.12 website
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.12 website
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.12 website
[root@test1 conf]# links --dump
http://10.0.10.11
                           this is 10.0.10.12 website
[root@test1 conf]#

由上面的信息進行對比,可見backup已經生效。。。

 


  
4)測試proxy_next_upstream故障轉移的功能
修改nginx.conf的配置文件以下:
     location / {
                proxy_redirect off;
                proxy_pass  
http://backend;
                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_next_upstream http_500 http_502 http_503 error timeout invalid_header;
        }
         
   upstream  backend {
        server 10.0.10.11:8080;
        server 10.0.10.12:80;
        }

#service nginx configtest
#service nginx restart

測試:
 從上面的配置看,upstream如今是默認的輪詢負載均衡機制,默認狀況下,會輪詢到兩臺服務器上,如今要模擬proxy_next_upstream中的一個錯誤來看效果。我這裏採用在10.0.10.12後端主機上使用iptables禁止80端口的訪問,測試當輪詢到10.0.10.12這臺主機上時,因爲禁止訪問會致使超時,此時會返回10.0.10.11上的站點內容

[root@test1 log]# links --dump http://10.0.10.11
                           this is 10.0.10.11 website
[root@test1 log]# links --dump
http://10.0.10.11
                           this is 10.0.10.11 website
[root@test1 log]#

由上面的信息可知,測試效果已經生效。。。。第二次的請求時會有一個超時的時間須要等待一會,但畢竟是實驗環境,線上環境時不可能這麼長,但足以說明效果是達到了。。。

 

注:upstream的相關功能就測試這麼幾個,其餘的內容都是同樣的測試機制,若是有須要請自行測試。。。  
  
  
9.nginx fastcgi配置
 nginx的fastcgi接口是用來整合php,將客戶端對php的頁面請求,轉發到後端的php服務器上,由php程序進行解析並返回結果

基本的配置:
 location ~ \.php$ {
            root        /usr/local/nginx/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
       #     fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
   
以上配置說明,將php文件轉發給後端的php服務器,這裏的fastcig_pass指定的是本地,若是nginx和php服務器不是同一臺,則要修改php的監聽地址,而後將這裏的地址該爲php服務器的地址。具體測試這裏不在贅述,在LNMP中都有...

fastcgi的優化:
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
以上內容能夠放在http{}段,也能夠放在location{}段

fastcgi cache設置:
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m max_size=10g;
以上兩行內容必須放在http{}段

下面的內容放在server{}段中
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_key $host$request_uri;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_client_abort on;
相關解釋:
fastcgi_cache_path:該選項用來定義fastcgi的緩存目錄的信息。/usr/local/nginx/fastcgi_cache 這是緩存的目錄文件 levels 設置緩存目錄的子目錄級別1:2 表示容許二級子目錄,一般一級子目錄容許16個,二級子目錄容許256個,以此類推,keys_zone用來設置內層緩存區的緩存名和緩存大小 inactive 用來設置緩存的過時時間,max_size 表示容許使用硬盤做爲緩存的最大空間

fastcgi_cache_valid:定義哪些狀態碼的請求要緩存
fastcgi_cache_min_uses:URL通過多少次請求將被緩存
fastcgi_cache_use_stale:定義哪些狀況下用過時緩存
fastcgi_cache_key:定義fastcgi_cache的key,示例中就以請求的URI做爲緩存的key,Nginx會取這個key的md5做爲緩存文件,若是設置了緩存哈希目錄,Nginx會從後往前取相應的位數作爲目錄
fastcgi_cache:用哪一個緩存空間

注意:設置不是必定的,能夠根據本身的須要進行調整。。。。此外fastcgi還有不少其餘的設置,更多的請看官方手冊

爲了給你們一個直觀的感覺,我這裏仍是測試一下fastcgi的緩存效果。。。
修改前端代理nginx.conf:
http{}段增長:
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m max_size=10g;
add_header X-Cache-TEST "$upstream_cache_status - $upstream_response_time";     //用來在瀏覽器響應頭部中查看緩存是否命中

server段{}中:
location ~ \.php$ {
            root           html;
            fastcgi_pass   10.0.10.12:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_cache TEST;
            fastcgi_cache_valid 200 302 1h;
            fastcgi_cache_valid 301 1d;
            fastcgi_cache_valid any 1m;
            fastcgi_cache_key $host$request_uri;
            fastcgi_cache_methods GET HEAD;
            fastcgi_cache_min_uses 1;
            fastcgi_cache_use_stale error timeout invalid_header http_500;
            fastcgi_ignore_client_abort on;
            include        fastcgi_params;
        }

#service nginx configtest
#service nginx restart
#mkdir /usr/local/nginx/fastcgi_cache //建立緩存目錄

配置後端10.0.10.12服務器:
修改/usr/local/php55/etc/php-fpm.conf:
#listen = 127.0.0.1:9000
listen = 10.0.10.12:9000

#pkill php-fpm
#/usr/local/php55/sbin/php-fpm //重啓php-fpm進程


測試:

 

wKiom1P9mzziZswiAAN1-5xgPko431.jpg

 


從上面的信息能夠看出,第一次訪問時,狀態爲MISS,可是緩存目錄已經有緩存產生了,第二次訪問時,顯示HIT,說明緩存命中

 

10.nginx proxy_cache緩存配置
 nginx自己支持proxy_cache的緩存設置,一般能夠用來將後端服務器的靜態頁面,圖片文件等緩存到本地的一個目錄中,在緩存失效期間內,當客戶端再次請求時,會直接從緩存中響應,而
不須要從後端服務器再次獲取。
exmaple:
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;

        location ~ .*\.(gif|jpg|png|htm|html|css|js|flv|ico|swf)(.*) {
              proxy_pass
http://backend;
              proxy_redirect off;
              proxy_set_header Host $host;
              proxy_cache cache_one;
              proxy_cache_valid 200 302 1h;
              proxy_cache_valid 301 1d;
              proxy_cache_valid any 1m;
              expires 30d;    //這個是設置客戶端瀏覽器對匹配的內容緩存的時間,跟proxy_cache無多大關係
        }


測試的方法和fastcgi_path相似,這裏不在贅述,有問題留言。。。


注:通過網友的多翻測試,對於頁面緩存的設置,一般要考慮兩個方面的內容,一個是後端源服務器頁面頭部設置的緩存,二個是nginx自身設置的緩存策略。一般能設置緩存策略的對象有,nginx inactive,nginx expires,源服務器exipres,源服務器max-age,nginx proxy_cache_valid
這些選項都能對緩存的過時時間產生影響,其影響過時時間的優先級是:inactive,源服務器expires,源服務器max-age,nginx proxy_cache_valid .

注意:當nginx expires 和源服務器的expires衝突時,對於客戶端而言,將以nginx的expires爲準,而對於nginx而言緩存文件的expires時間以源服務器的expires設置爲準


11.nginx 內核優化配置
 爲了使nginx所在的服務器可以提供更好的性能,不得不根據實際狀況對內核進行優化。。下面的優化是網上的一個見的比較多的設置,你喜歡就用吧。。
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000

 

 


12.nginx 防盜鏈的配置
 Nginx的防盜鏈功能也很是強大。在默認狀況下,只須要進行簡單的配置,便可實現防盜鏈處理。
 要實現防盜鏈,就須要使用valid_referers指令,官方的樣例:
 valid_referers none blocked server_names
               *.example.com example.*
www.example.org/galleries/
               ~\.google\.;

if ($invalid_referer) {
    return 403;
}

解釋:
valid_referers :用來設置符合條件的域名或URL
 none:表示referer字段爲空的
 blocked:來源頭部的referer不爲空,可是被防火牆和代理給刪除了,這些都不是以http://或者https://開頭的
 server_names:表示referer字段中包含了本地域名
 string:任何正則表達式在域名中匹配的域名
 
若是域名不符合valid_referers中設置的,invalid_referer變量的值就爲1,此時就會執行if中的語句

具體解釋請看官網

一個簡單的模擬案例:
前端nginx設置:
wKioL1P9nFSAhyb8AACUnqfEPS0104.jpg

如上圖所示,在主server{}中增長一個別名c.liwei.com

 

而後在server{}段中添加一個額關於jpg的location設置:

        location ~* .*\.(jpg)?$ {
                proxy_redirect off;
                proxy_pass
http://backend;
                valid_referers none blocked lxm.com *.lxm.com;
                if ($invalid_referer) {
                #return 403;
                rewrite ^/
http://10.0.10.12/error.html;
        }
表示匹配jpg的圖片都轉發到後端,而且設置了防盜鏈規則

#service nginx configtest
#service nginx restart

後端服務器:10.0.10.12
修改/usr/local/nginx/html/index.html內容以下:
wKiom1P9mz3DPXdOAAChGK_ezSI320.jpg

注意:這裏作了一個picture的鏈接,使用的是c.liwei.com

在建立一個error.html文件:
wKioL1P9nFTz3rvZAAEHfTSQMNo571.jpg

在上傳一個圖片error.jpg的測試圖片到/usr/local/nginx/html/error.jpg(圖片內容隨你本身)

測試:
第一次:
http://a.lxm.com/error.jpg  直接訪問圖片,此時是以域名a.lxm.com來訪問的,能夠訪問
wKiom1P9mz2T9Q9kAAIJSpQtI4o888.jpg

第二次:http://c.liwei.com  此時返回的是帶有picture鏈接的頁面,點擊picture鏈接,返回的是error.html的頁面內容,說明訪問被拒絕而且頁面作了重寫規則

wKioL1P9nFXSR56ZAADoX0C253w034.jpg

 

wKiom1P9mz3j8cVqAADvOJW4MWA196.jpg

 


注:要作更加複雜的防盜鏈處理,可使用Nginx的HttpAccessKeyModule,經過這個模塊能夠實現功能更強大的防盜鏈處理,更詳細的參考官方文檔。

 


13.nginx 重寫規則
rewrite經常使用的正則匹配:
* ~ 爲區分大小寫匹配
* ~* 爲不區分大小寫匹配
* !~和!~*分別爲區分大小寫不匹配及不區分大小寫不匹配
下面是能夠用來判斷的表達式:
-f和!-f用來判斷是否存在文件
-d和!-d用來判斷是否存在目錄
-e和!-e用來判斷是否存在文件或目錄
-x和!-x用來判斷文件是否可執行

rewrite標記:
last – 該標記表示重寫url,可是重寫以後還會從新發起server段的請求,所以使用該標記以後,必定要注意會不會引發url重寫的死循環
break – 該標記表示重寫url,可是重寫當前url規則後,就終止後續rewrite的執行
redirect – 返回臨時重定向的HTTP狀態302,瀏覽器中的url地址會跳轉
permanent – 返回永久重定向的HTTP狀態301,瀏覽器中的url地址會跳轉

下面是能夠用做判斷的全局變量
例:
http://localhost:80/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:
http://localhost:80/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

案例:
server {
listen 80;
server_name a.lxm.com;
index index.html index.php;
root html;
if ($host !~ 「.*\.lxm\.com") {
rewrite ^(.*)
http://10.0.10.12/error.html last;
}
}

基本上rewrite就是這樣的用法,主要的是要知道不一樣的變量所表明的函數以及正則表達式的書寫,根據須要自行測試

14.nginx 防惡意解析
 爲了防止域名惡意解析***,能夠給nginx設置一個默認的虛擬主機來匹配這些非正常的解析,可是該虛擬主機必須放在全部server{}段的首部
配置:
server {
 listen 80 default_server;
 return 403;  //這裏也可使用rewrite等其餘方法
}

測試:隨便使用一個未設置的主機名

 wKioL1P9nFWDSJv-AAFMSHIQAAw050.jpg

 

由上面可知,訪問被拒絕,防止惡意解析生效。。。。
 

 

到此,nginx基本的必知必會就聊到這裏了,聊的好累,本人都是全程文本測試,爲了給你們展現還截了各類奇葩的圖,你說你怎麼謝我吧。。。。。哈哈。

 

結束!!!

    笨蛋的技術------不怕你不會!!!!

相關文章
相關標籤/搜索