1. 程式人生 > >Linux實戰教學筆記27:Nginx詳細講解

Linux實戰教學筆記27:Nginx詳細講解

配置 規範化 解釋 重要 代理服務 ini require 擁有 層次

前言:nginx的特點

本節主要對Nginx Web服務軟件進行介紹,涉及Nginx的基礎,特性,配置部署,優化,以及企業中的日常運維管理和應用。作為HTTP服務軟件的後起之秀,Nginx與它的老大哥Apache相比有很多改進之處,比如,在性能上,Nginx占用的系統資源更少,能支持更多的並發連接(特別是靜態小文件場景下),達到更高的訪問效率;在功能上,Nginx不但是一個優秀的Web服務軟件,還可以作為反向代理負載均衡及緩存服務使用;在安裝配置上,Nginx更為方便,簡單,靈活,可以說,Nginx是一個極具發展潛力的Web服務軟件。

Nginx是什麽?

  • nginx是一個開源的,支持高性能,高並發的www服務和代理服務軟件。
  • nginx因具有高並發(特別是靜態資源),占用系統資源少等特性,且功能豐富而逐漸流行起來。
  • nginx不但是一個優秀Web服務軟件,還具有反向代理負載均衡功能和緩存服務功能,與lvs負載均衡及Haproxy等專業代理軟件相比,Nginx部署起來更為簡單,方便;在緩存功能方面,它又類似於Squid等專業的緩存服務軟件。

Nginx的重要面試知識

Nginx的重要特性

  • 支持高並發:能支持幾萬並發連接(特別是靜態小文件業務環境)
  • 資源消耗少:在3萬並發連接下,開啟10哥Nginx線程消耗的內存不到200MB
  • 可以做HTTP反向代理及加速緩存,即負載均衡功能,內置對RS節點服務器健康檢查功能,這相當於專業的Haproxy軟件或LVS的功能
  • 具備Squid等專業緩存軟件等的緩存功能。
  • 支持異步網絡I/O事件模型epoll(linux2.6+)。

Nginx軟件的主要企業功能應用

(1)作為Web服務軟件

Nginx是一個支持高性能,高並發的Web服務軟件,它具有很多優秀的特性,作為Web服務器,與Apache相比,Nginx能夠支持更多的並發連接訪問,但占用的資源更少,效率更高,在功能上也強大了很多,幾乎不遜色於Apache。

(2)反向代理或負載均衡服務

在反向代理或負載均衡服務方面,Nginx可以作為Web服務,PHP等動態服務及Memcached緩存的代理服務器,它具有類似專業反向代理軟件(如Haproxy)的功能,同時也是一個優秀的郵件代理服務軟件,但是Nginx的代理功能還是相對簡單了些,特別是不支持TCP的代理(Nginx1.9.0版本已經開始支持TCP代理了)

(3)前端業務數據緩存服務

在Web緩存服務方面,Nginx可通過自身的proxy_cache模塊實現類Squid等專業緩存軟件的功能。

綜上:Nginx的這三大功能(Web服務,反向代理或負載均衡服務,前端業務數據緩存服務)是國內使用Nginx的主要場景,特別是前兩個。

Web 服務產品性能對比測試

從下圖中可以看出處理靜態小文件(小於1MB時),Nginx和Lighttpd比Apache更有優勢,Nginx處理小文件的優勢明顯,Lighttpd綜合最強。

技術分享圖片

下圖是各類Web服務器在動態數據性能上的對比,從圖中可以看出,在處理動態數據時,三者的差距不大,Apache更有優勢一點。這是因為處理動態數據的能力取決於PHP(java)和後端數據庫的服務能力,也就是說瓶頸不在Web服務器上。一般情況下普通PHP引擎支持的並發連接參考值為300~1000,Java引擎和數據庫的並發連接參考值為300~1500.業務場景及網站架構不同,並發連接數也會有上下浮動。

技術分享圖片

為什麽Nginx總體性能比Apache高?

  • Nginx使用最新的epoll(Linux2.6內核)和kqueue(freebsd)異步網絡I/O模型,而Apache使用的是傳統的select模型。目前Linux下能夠承受高並發訪問的Squid,Memcached軟件采用的都是epoll模型。
  • 處理大量連接的讀寫時,Apache所采用的select網絡I/O模型比較低效。

技術分享圖片

技術分享圖片

如何正確選擇Web服務器

雖然國內很多人都在使用Nginx,但是Apache,Lighttpd這兩個Web服務器同樣非常強大且實用,尤其時Apache,到目前為止仍是全球使用最廣泛的Web服務軟件。
在實際工作,我們需要根據業務需求來選擇合適的業務服務軟件,有關Web服務,建議如下。

  • 靜態業務:若是高並發場景,盡量采用Nginx或Lighttpd,二者首選Nginx。
  • 動態業務:理論上采用Nginx和Apache均可,建議選擇Nginx,為了避免相同業務的服務軟件多樣化,增加額外維護成本。動態業務可以由Nginx兼做前端代理,再根據頁面元素的類型或目錄,轉發到後端相應的服務器進行處理。
  • 既有靜態業務又有動態業務:采用Nginx

此外,如果並發不是很大,又對Apache很熟悉,采用Apache也是可以的,Apache2.4版本也很強大,並發連接數也有所增加。總的來說,在滿足需求的前提下,首先選擇自己最擅長的軟件,若發現了更好的軟件,可在掌握新軟件之後逐步替換。雖然動態和靜態業務都傾向於選擇Nginx,但是大前提是自己要熟練掌握Nginx。切記,在工作中不要盲目選擇軟件,這可能最終會導致自己無法控制局面,從而給企業帶來災難性的損失。

1,nginx的編譯安裝部署


yum install -y pcre-devel openssl-devel         #用本地yum倉庫安裝依賴包
#wget -q http://nginx.org/download/nginx-1.10.2.tar.gz     #下載軟件源碼包
useradd -s /sbin/nologin -M www     #創建程序用戶
tar xf nginx-1.10.2.tar.gz -C /usr/src/     #解壓縮
cd /usr/src/nginx-1.10.2
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module       #預配置
make && make install        #編譯和安裝
ln -s /usr/local/nginx/sbin/* /usr/local/sbin/  #給命令做軟連接,以便PATH能找到
/usr/local/nginx/sbin/nginx #啟動nginx

特別提示:
/usr/local/nginx/sbin/nginx -s reload nginx平滑重啟命令
/usr/local/nginx/sbin/nginx -s stop nginx停止服務命令

1.1 web排錯三部曲下面介紹客戶端排查的思路

第一步,在客戶端上ping服務器端IP,命令如下:

ping 10.0.0.8排除物理線路問題影響

第二步,在客戶端上telnet服務器端IP,端口,命令如下:

telnet 10.0.0.8 80排除防火墻等得影響

第三步,在客戶端使用wget命令檢測,如下:

wget 10.0.0.8(curl -I 10.0.0.8)模擬用戶訪問,排除http服務自身問題,根據輸出在排錯

提示:
以上三步是客戶端訪問網站異常排查的重要三部曲。

2,Nginx主配置文件nginx.conf

Nginx主配置文件nginx.conf是一個純文本類型的文件(其他配置文件大多也是如此),它位於Nginx安裝目錄下的conf目錄,整個配置文件是以區塊的形式組織的。一般,每個區塊以一個大括號“{}”來表示,區塊可以分為幾個層次,整個配置文件中Main區位於最上層,在Main區下面可以有Events區,HTTP區等層級,在HTTP區中又包含有一個或多個Server區,每個Server區中又可有一個或多個location區,整個Nginx配置文件nginx.conf的主體框架為:

[root@chensiqi conf]# egrep -v "#|^$" nginx.conf #去掉包含#號和空行的內容
worker_processes  1; #worker進程的數量
error_log  logs/error.log;  #錯誤日誌(默認沒開)
pid        logs/nginx.pid;  #進程號(默認沒開)
events {    #事件區塊開始
    worker_connections  1024;   #每個worker進程支持的最大連接數
}           #事件區塊結束
http {      #http區塊開始
    include       mime.types;   #Nginx支持的媒體類型庫文件包含
    default_type  application/octet-stream; #默認的媒體類型
    sendfile        on;     #開啟高效傳輸模式
    keepalive_timeout  65;  #連接超時。
    server {      #網站配置區域(第一個server第一個虛擬主機站點)
        listen       80;    #提供服務的端口,默認80
        server_name  www.chensiqi.org; #提供服務的域名主機名
        location / {    #第一個Location區塊開始
            root   html;  #站點的根目錄(相對於nginx安裝路徑)
            index  index.html index.htm; #默認的首頁文件,多個用空格分開
        }
        error_page 500 502 503 504  /50x.html;  #出現對應的http狀態碼時,使用50x.html回應客戶
        location = /50x.html {  #Location區塊開始,訪問50x.html
            root   html;     #指定對應的站點目錄為html
        }
    }
    server {      #網站配置區域(第二個server第二個虛擬主機站點)
        listen       80;    #提供服務的端口,默認80
        server_name  bbs.chensiqi.org; #提供服務的域名主機名
        location / {    #服務區塊
            root   html;  #相對路徑(nginx安裝路徑)
            index  index.html index.htm;
        }
        location = /50x.html { #發生錯誤訪問的頁面
            root   html;
        }
    }
}

整個nginx配置文件的核心框架如下:

worker_processes 1;
events {
    
    worker_connections 1024;

}
http {
    include mime.types;
    server {
        listen  80;
        server_name localhost;
        location / {
            root  html;
            index  index.html index.htm;
        }
    }
}

3,Nginx其他配置文件

  • 如果是配合動態服務(例如PHP服務),Nginx軟件還會用到擴展的fastcgi相關配置文件,這個配置是通過在Nginx.conf主配置文件中嵌入include命令來實現的,不過默認情況是註釋狀態,不會生效。

  • fastcgi.conf配置文件的初始內容如下:

[root@localhost conf]# cat fastcgi.conf

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
  • fastcgi_params 默認配置文件的內容如下:
[root@localhost conf]# cat fastcgi_params

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

上述未做註釋的目錄或文件是比較少用的,有關動態擴展配置後文講到PHP服務時再來講解。

4,Nginx的功能模塊說明

技術分享圖片

5,Nginx虛擬主機配置實戰

5.1 虛擬主機概念和類型介紹

5.1.1 虛擬主機概念

所謂虛擬主機,在Web服務裏就是一個獨立的網站站點(www.baidu.org),這個站點對應獨立的域名(也可能是IP或端口),具有獨立的程序及資源目錄,可以獨立地對外提供服務供用戶訪問。
這個獨立的站點在配置裏是由一定格式的標簽段標記,對於Apache軟件來說,一個虛擬主機的標簽段通常被包含在

5.1.2 虛擬主機類型

常見的虛擬主機類型有如下幾種。

  • 基於域名的虛擬主機

所謂基於域名的虛擬主機,意思就是通過不同的域名區分不同的虛擬主機,基於域名的虛擬主機是企業應用最廣的虛擬主機類型,幾乎所有對外提供服務的網站都是使用基於域名的虛擬主機,例如:www.etiantian.org

  • 基於端口的虛擬主機

同理,所謂基於端口的虛擬主機,意思就是通過不同的端口來區分不同的虛擬主機,此類虛擬主機對應的企業應用主要為公司內部的網站,例如:一些不希望直接對外提供用戶訪問的網站後臺等,訪問基於端口的虛擬主機地址裏要帶有端口,例如:http://www.baidu.com:80

  • 基於IP的虛擬主機

同理,所謂基於IP的虛擬主機,意思就是通過不同的IP區分不同的虛擬主機,此類虛擬主機對應的企業應用非常少見,一般不同業務需要使用多IP的場景都會在負載均衡器上進行VIP綁定,而不是在Web上通過綁定IP區分不同的虛擬機。
三種虛擬主機類型均可獨立使用,也可以互相混合一起使用,同學們應把基於域名的虛擬主機類型當作重點來學習掌握,其他的兩個類型了解即可。

5.2 基於域名的虛擬主機配置實戰

說明:本節內容再生產場景中是最常用到的,因此,同學們要優先並且熟練掌握。

5.2.1 配置基於域名的nginx.conf內容

這裏使用grep過濾命令來生成基礎的Nginx主配置文件nginx.conf,然後根據生成的初始配置進行修改,使其成為所需的形式,具體步驟為:

[root@localhost conf]# pwd
/application/nginx/conf
[root@localhost conf]# egrep -v "#|^$" nginx.conf.default >nginx.conf

或者幹脆直接新創建配置文件nginx.conf,然後編輯,輸入如下內容:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html/www;
            index  index.html index.htm;
        }
    }
}

編輯完配置文件後,我們需要檢查語法

[root@localhost conf]# /application/nginx/sbin/nginx -t
nginx: the configuration file /application/nginx-1.10.2//conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx-1.10.2//conf/nginx.conf test is successful

然後由於web的存放路徑是相對路徑,因此我們需要創建個目錄,

技術分享圖片

[root@localhost html]# cd /application/nginx/html/
[root@localhost html]# ls
50x.html  index.html            #原本的網頁文件
[root@localhost html]# mkdir www   #創建一個目錄叫做www
[root@localhost html]# echo "I am www" > www/index.html  #寫入網頁文件
[root@localhost html]# cat www/index.html   #查看一下
I am www
[root@localhost html]# curl 192.168.0.100  #測試鏈接
I am www

接下來,我們再創建一個域名的網站,配置文件如下

技術分享圖片
註意:修改配置文件需要重啟動nginx

給第二個網站添加網頁文件

[root@localhost html]# ls
50x.html  index.html  www
[root@localhost html]# mkdir bbs
[root@localhost html]# echo "I am bbs" > bbs/index.html

通過測試,我們發現,永遠都只能看到第一個網站

[root@localhost html]# curl 192.168.0.100
I am www
[root@localhost html]# curl 192.168.0.100
I am www
[root@localhost html]# curl 192.168.0.100
I am www
[root@localhost html]# curl 192.168.0.100
I am www

這是因為通過IP地址來訪問的話,nginx並不知道你想要訪問哪個站點,因此,他默認你是要訪問他配置文件裏的第一個站點,也就是www.chensiqi.com
通過修改hosts映射我們可以訪問不同的站點。

修改hosts映射文件

[root@localhost html]# echo "192.168.0.100 www.chensiqi.com bbs.chensiqi.com" >> /etc/hosts
[root@localhost html]# tail -1 /etc/hosts
192.168.0.100 www.chensiqi.com bbs.chensiqi.com

現在我們再進行訪問測試

[root@localhost html]# curl www.chensiqi.com
I am www
[root@localhost html]# curl www.chensiqi.com
I am www
[root@localhost html]# curl bbs.chensiqi.com
I am bbs
[root@localhost html]# curl bbs.chensiqi.com
I am bbs

如上所示:基於域名的虛擬主機配置完畢。我們在工作中遇到的基本都是這種類型的網站。配置過程需要重點練習。其他類型,了解即可。

6 Nginx常用功能配置實戰

6.1 規範化Nginx配置文件

下面是優化後的Nginx配置的實戰方案

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    include extra/www.conf;   #虛擬網站配置信息統一放在了當前的extra目錄下
    include extra/mail.conf;
    include extra/status.conf;

}
[root@localhost nginx]# tree conf/extra/
conf/extra/
├── mail.conf
├── status.conf
└── www.conf

0 directories, 3 files
[root@localhost nginx]# cat conf/extra/www.conf 
    server {
        listen       80;
        server_name  www.yunjisuan.com;
        location / {
            root   /var/www/html/wwwcom;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /var/www/html;
        }
    }

6.2 Nginx狀態信息功能實戰

6.2.1 確認編譯時是否設定了此模塊

root@localhost nginx]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.10.2
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx-1.10.2/ --with-http_stub_status_module --with-http_ssl_module

##說明
--with-http_stub_status_module模塊就是狀態信息模塊

6.2.2 設定信息模塊配置

[root@localhost nginx]# cat conf/extra/status.conf 
##status


server{

    listen  80;
    server_name  status.yunjisuan.com;
    location / {
       stub_status  on;   #開啟狀態信息功能
           access_log   off;  #不記錄訪問日誌

         }
}  

##說明
狀態信息模塊配置方式和搭建虛擬網站類似需要占用一個域名來訪問

註意:需要重啟Nginx服務

6.2.3 Nginx status顯示結果詳解

[root@localhost nginx]# curl status.yunjisuan.com
Active connections: 2 #表示Nginx正在處理的活動連接2個
server accepts handled requests
 39 39 41 
Reading: 0 Writing: 1 Waiting: 1 

第一個server表示Nginx啟動到現在2共處理了39個連接
第二個accepts表示Nginx啟動到現在共成功創建了39次握手
請求丟失數=(握手數-連接數),可以看出,本次狀態顯示沒有丟失請求。
第三個handled requests,表示總共處理了41次請求。
Reading為Nginx讀取到客戶端的Header信息數
Writing為Nginx返回給客戶端的Header信息數
Waiting為Nginx已經處理完正在等候下一次請求指令的駐留連接。在開啟keep-alive的情況下,這個值等於active - (reading+writing)

特別提示:

出於安全起見,這個狀態信息要防止外部用戶查看。

6.3 增加錯誤日誌

範例:error_log file level;

常見的日誌級別【debug|info|notice|warn|error|crit|alert|emerg】
生產場景一般是warn|error|crit這三個級別之一,註意不要配置info等較低級別,會帶來巨大磁盤I/O消耗。
error_log的默認值為:
# default:error_log logs/error.log error;

worker_processes  1;
error_log  logs/error.log;    #非常簡單,一般增加此行即可
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    include extra/www.conf;
    include extra/mail.conf;
    include extra/status.conf;

}

6.4 Nginx訪問日誌輪詢切割

默認情況下Nginx會把所有的訪問日誌生成到一個指定的訪問日誌文件access.log裏,但這樣一來,時間長了就會導致日誌個頭很大,不利於日誌的分析和處理,因此,有必要對Nginx日誌,按天或按小時進行切割,使其分成不同的文件保存。

[root@localhost nginx]# cat /server/scripts/cut_nginx_log.sh 
#!/bin/bash
#日誌切割腳本可掛定時任務,每天00點整執行

Dateformat=`date +%Y%m%d`
Basedir="/usr/local/nginx"
Nginxlogdir="$Basedir/logs"
Logname="access"

[ -d $Nginxlogdir ] && cd $Nginxlogdir || exit 1
[ -f ${Logname}.log ] || exit 1
/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log
$Basedir/sbin/nginx -s reload

[root@localhost nginx]# cat >>/var/spool/cron/root << KOF
#cut nginx access log by Mr.chen
00 00 * * * /bin/bash /server/scripts/cut_nginx_log.sh >/dev/null 2>&1

6.5 Nginx location

6.5.1 location使用的語法為:

location [ = | ~ | ~* | ^~ ] uri {

  ...

}

上圖是對location語法的說明。上述語法中的URI部分是關鍵,這個URI可以是普通的字符串地址路徑,或者是正則表達式,匹配成功則執行後面大括號裏的相關命令。正則表達式的前面還可以有“~”或“~*”等特殊字符。

技術分享圖片

匹配這兩種特殊字符“~”或“~*”的區別為:“~”用於區分大小寫(大小寫敏感)的匹配;“~*”用於不區分大小寫的匹配。還可以用邏輯操作符“!”對上面的匹配取反,即“!~”和“!~*”。此外,“^~”的作用是先進行字符串的前綴匹配(必須以後邊的字符串開頭),如果能匹配到,就不再進行其他location的正則匹配了。

6.5.2 location匹配示例

[root@localhost nginx]# cat /usr/local/nginx/conf/extra/www.conf 
    server {
        listen       80;
        server_name  www.yunjisuan.com;
    root    /var/www/html/wwwcom;
        location / {
        return 401;     
        }
    location = / {
        return 402;
    }
    location = /images/ {
        return 501;
    }
    location /documents/ {
        return 403;
    }
    location ^~ /images/ {
        return 404;
    }
    location ~* \.(gif|jpg|jpeg)$ {
        return 500;
    }
    
    }

正則匹配結果如下:

[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com
402        #匹配了=的情況
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/
402         #匹配了=的情況
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/xxxx
401         #匹配不到默認匹配 /的情況
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/documents/
403         #匹配字符串
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/images/
501         #優先匹配=的情況
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/images/1.jpg
404         #匹配
[root@localhost nginx]# curl -s -o /dev/null -w "%{http_code}\n" www.yunjisuan.com/documents/images/1.jpg
500         #匹配~*的情況

從多個location的配置匹配可以看出匹配的優先順序

順序 匹配標識的location 匹配說明
1 " location = / { " 精確匹配
2 " location ^~ /images/ { " 先進行字符串的前綴匹配,如果匹配到就不做正則匹配檢查
3 " loction ~* \.(gif | jpg | jpeg)$ { " 正則匹配,*為不區分大小寫
4 " location /documents/ { " 匹配常規字符串,模糊匹配,如果有正則檢查,正則優先
5 " location / { " 所有location都不能匹配後的默認匹配原則

6.6 Nginx rewrite

6.6.1 什麽是Nginx rewrite?

和Apache等Web服務軟件一樣,Nginx rewrite的主要功能也是實現URL地址重寫。Nginx的rewrite規則需要PCRE軟件的支持,即通過Perl兼容正則表達式語法進行規則匹配。默認參數編譯時,Nginx就會安裝支持rewrite的模塊,但是,也必須要有PCRE軟件的支持。

6.6.2 Nginx rewrite 語法

(1)rewrite指令語法

指令語法:rewrite regex replacement 【flag】;
默認值:none
應用位置:server,location,if
rewrite是實現URL重寫的關鍵指令,根據regex(正則表達式)部分的內容,重定向到replacement部分,結尾是flag標記。下面是一個簡單的URL rewrite跳轉例子:

rewrite ^/(.*) http://www.baidu.com/$1  permanent;

在上述指令中,rewrite為固定關鍵字,表示開啟一條rewrite匹配規則,regex部分是^(.*),這是一個正則表達式,表示匹配所有,匹配成功後跳轉到http://www.baidu.com/$1 。這裏的$1是取前面regex部分括號裏的內容,結尾的permanent;是永久301重定向標記,即跳轉到後面的http://www.baidu.com/$1 地址上。

(2)regex常用正則表達式說明

技術分享圖片

(3)rewrite指令的最後一項參數flag標記的說明

技術分享圖片

  • 在以上的flag標記中,last和break用來實現URL重寫,瀏覽器地址欄的URL地址不變,但在服務器端訪問的程序及路徑發生了變化。redirect和permanent用來實現URL跳轉,瀏覽器地址欄會顯示跳轉後的URL地址。
  • last和break標記的實現功能類似,但二者之間有細微的差別,使用alias指令時必須用last標記,使用proxy_pass指令時要使用break標記。last標記在本條rewrite規則執行完畢後,會對其所在的server{...}標簽重新發起請求,而break標記則會在本條規則匹配完成後,終止匹配,不再匹配後面的規則。

6.6.3 Nginx rewrite 的企業應用場景

Nginx的rewrite功能在企業裏應用非常廣泛:

  • 可以調整用戶瀏覽的URL,使其看起來更規範,合乎開發及產品人員的需求。
  • 為了讓搜索引擎收錄網站內容,並讓用戶體驗更好,企業會將動態URL地址偽裝成靜態地址提供服務
  • 網站換新域名後,讓舊域名的訪問跳轉到新的域名上,例如:讓京東的360buy換成了jd.com
  • 根據特殊變量,目錄,客戶端的信息進行URL跳轉等。

6.6.4 Nginx rewrite 301 跳轉

以往我們是通過別名方式實現yunjisuan.com和www.yunjisuan.com訪問同一個地址的,事實上,除了這個方式外,還可以使用nginx rewrite 301 跳轉的方式來實現。實現的配置如下:

[root@localhost nginx]# cat conf/extra/www.conf 
#www virtualhost by Mr.chen   
    server {
        listen       80;
        server_name  www.yunjisuan.com;
    root    /var/www/html/wwwcom;
        location / {
        index index.html index.htm;
        }
#   location = / {
#       return 402;
#   }
    location = /images/ {
        return 501;
    }
    location /documents/ {
        return 403;
    }
    location ^~ /images/ {
        return 404;
    }
    location ~* \.(gif|jpg|jpeg)$ {
        return 500;
    }
    
    }

    server{
        listen  80;
        server_name yunjisuan.com;
        rewrite ^/(.*)  http://www.yunjisuan.com/$1 permanent;
        #當用戶訪問yunjisuan.com及下面的任意內容時,都會通過這條rewrite跳轉到www.yunjisuan.com對應的地址
    }

客戶端訪問測試結果

技術分享圖片

技術分享圖片

6.6.5 實現不同域名的URL跳轉

示例:實現訪問http://mail.yunjisuan.com時跳轉到http://www.yunjisuan.com/mail/yunjisuan.html

外部跳轉時,使用這種方法可以讓瀏覽器地址變為跳轉後的地址,另外,要事先設置http://www.yunjisuan.com/mail/yunjisuan.html有結果輸出,不然會出現401等權限錯誤。

(1)配置Nginx rewrite規則

[root@localhost nginx]# cat conf/extra/mail.conf 
    server {
        listen       80;
        server_name  mail.yunjisuan.com;
        location / {
            root   /var/www/html/mailcom;
            index  index.html index.htm;
        }
    if ( $http_host ~* "^(.*)\.yunjisuan\.com$") {
        set $domain $1;
        rewrite ^(.*) http://www.yunjisuan.com/$domain/yunjisuan.html break;

    }
}

客戶端訪問測試

技術分享圖片

技術分享圖片

6.6.6 rewrite跳轉標記flag使用總結

1,在根location(即location / {...})中或server{...} 標簽中編寫rewrite規則,建議使用last標記
2,在普通的location(例 location/yunjisuan/{...}或if{}中編寫rewrite規則,則建議使用break標記)

6.7 Nginx訪問認證

有時,在實際工作中企業要求我們為網站設置訪問賬號和密碼權限,這樣操作後,只有擁有賬號密碼的用戶才可以訪問網站內容。
這種使用賬號密碼才可以訪問網站的功能主要應用在企業內部人員訪問的地址上,例如:企業網站後臺,MySQL客戶端phpmyadmin,企業內部的CRM,WIKI網站平臺。

6.7.1 創建密碼文件

我們可以借用apache的htpasswd軟件,來創建加密的賬號和密碼

[root@localhost ~]# which htpasswd
[root@localhost ~]# htpasswd -bc /usr/local/nginx/conf/htpasswd yunjisuan 123123
Adding password for user yunjisuan   
[root@localhost ~]# cat /usr/local/nginx/conf/htpasswd 
yunjisuan:FC1/eEc/iK0Mo   #賬號密碼是加密的(htpasswd是文件的名字)

6.7.2 在虛擬主機配置文件裏加入兩條配置信息

[root@localhost html]# cat /usr/local/nginx/conf/extra/blog.conf 
    server {
        listen       80;
        server_name  blog.yunjisuan.com;
        location / {
            root   /var/www/html/blogcom;
            index  index.html index.htm;
            auth_basic      "yunjisuan training";   #加入這條配置
            auth_basic_user_file    /usr/local/nginx/conf/htpasswd; #加入這條配置
        }
    }


#配置解釋:

auth_basic :驗證的基本信息選項(後邊跟著的雙引號裏就是驗證窗口的名字)
auth_basic_user_file :驗證的用戶文件(後邊根賬號密碼文件的絕對路徑)

6.7.3 網頁登陸驗證

技術分享圖片

技術分享圖片

技術分享圖片

6.8 Nginx相關問題解答

6.8.1 Tengine和Nginx是什麽關系?

Tengine是淘寶開源Nginx的分支,官方站點為http://tengine.taobao.org/

6.8.2 訪問Nginx時出現狀態碼“403 forbidden”的原因

(1)Nginx配置文件裏沒有配置默認首頁參數,或者首頁文件在站點目錄下沒有如下內容:

index index.php index.html index.htm;

(2)站點目錄或內部的程序文件沒有Nginx用戶訪問權限

(3)Nginx配置文件中設置了allow,deny等權限控制,導致客戶端沒有訪問權限。

7 本章知識點回顧

  1. Nginx的特性優點
  2. 主流Web動態靜態性能對比
  3. Apache select 和Nginx epoll 模型的區別(面試常考)
  4. 虛擬主機概念及類型分類詳解
  5. 基於域名和端口虛擬主機的介紹及搭建
  6. Nginx錯誤,訪問日誌,以及訪問日誌切割
  7. Nginx訪問狀態信息介紹及配置實踐。
  8. Nginx location介紹及配置實踐
  9. Nginx rewrite介紹及配置實踐
  10. Nginx Web訪問認證介紹及配置實踐

Linux實戰教學筆記27:Nginx詳細講解