1. 程式人生 > >Nginx Web 服務應用進階(2)

Nginx Web 服務應用進階(2)

Nginx 狀態資訊功能實戰:

Nginx status 介紹:

Nginx 軟體的功能模組中有一個 http_stub_status_module 模組,這個模組的主要功能是記錄 Nginx 的基本訪問狀態資訊,讓使用者瞭解 Nginx 的工作狀態,例如連線數等資訊。要想使用狀態模組,在編譯 Nginx 時必須增加該模組,可通過如下方法檢查編譯安裝 Nginx 時是否設定支援上述模組:

[[email protected] conf]# /application/nginx/sbin/nginx -V

nginx version: nginx/1.6.3

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)

TLS SNI support enabled

configure arguments: --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module

具體配置過程如下:

① 生成狀態配置,並增加狀態配置引數:

[[email protected] conf]# cat >>/application/nginx/conf/extra/status.conf<<EOF

> ##status

> server {

>        listen  80;

>        server_name status.etiantian.org;

>        location / {

>             stub_status on;

>             access_log  off;

>        }

>   }

> EOF

[[email protected] conf]# vi nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    # nginx vhosts config

    include extra/www.conf;

    include extra/bbs.conf;

    include extra/blog.conf;

    include extra/status.conf;   #  此處讓它包括。  

}

"nginx.conf" 15L, 338C written

在 Windows 配置 hosts 加上該域名:status.etiantian.org           

在瀏覽器上訪問該域名會返回 Nginx 的狀態資訊如下所示:

 

 

對上圖各個資訊的說明:如下所示【略】

 

 

提示:為安全起見,這個狀態資訊要防止外部使用者檢視。

Nginx 錯誤日誌資訊配置:

Nginx 錯誤日誌的介紹:

Nginx 軟體會把自身執行的故障資訊及使用者訪問的日誌資訊記錄到指定的日誌檔案裡。

Nginx 的錯誤資訊是除錯 Nginx 服務的重要手段,屬於核心功能模組(ngx_core_module)的引數,該引數名字為 error_log,可以放在 Main 區塊中全域性配置,也可以放置不同的虛擬主機中單獨記錄虛擬主機的錯誤資訊。

error_log 的語法格式及引數語法說明如下:

 error_log            file                 level   ;

  關鍵字           日誌檔案       錯誤日誌級別  

提示:關鍵字 error_log 不能改變,日誌檔案可以指定任意存放日誌的目錄

常的錯誤日誌級別:

常的錯誤日誌級別有 [ debug |info |notice |warm |error |crit |alert |emerg ],級別越高記錄的資訊越少。企業場景一般用 warm |error |crit 這三個級別之一,注意不要配置 debug(級別最低、打的最多)、info 等較低的級別,會消耗大量的磁碟 I/O 。

錯誤日誌 error_log 的預設值:

#default:  error_log logs/error.log  error;

可以放置的標籤段:

#context: main,http,server,location

錯誤日誌的配置:

[[email protected] conf]# vi nginx.conf

worker_processes  1;

error_log logs/error.log error;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    # nginx vhosts config

    include extra/www.conf;

    include extra/bbs.conf;

    include extra/blog.conf;

    include extra/status.conf;

}

 "nginx.conf" 16L, 370C written

[[email protected] conf]# ../sbin/nginx -t

[[email protected] conf]# ../sbin/nginx -s reload

[[email protected] conf]# ll ../logs/

total 16

-rw-r--r-- 1 root root 5431 Dec 21 01:16 access.log

-rw-r--r-- 1 root root 2782 Dec 21 03:37 error.log

-rw-r--r-- 1 root root    5 Dec 20 21:36 nginx.pid

[[email protected] conf]# cat ../logs/error.log        #  檢視 Nginx 錯誤日誌資訊。

[[email protected] conf]# > ../logs/error.log           #  清空 Nginx 錯誤日誌資訊。

[[email protected] conf]# ../sbin/nginx -s reload    #  平滑重啟。

[[email protected] conf]# cat ../logs/error.log         #  檢視 Nginx 錯誤日誌資訊。   

2017/12/21 03:39:17 [notice] 2852#0: signal process started  

Nginx 訪問日誌:

1、Nginx 訪問日誌的介紹:

Nginx 軟體會把每個使用者訪問網站的日誌資訊記錄到指定的日誌檔案裡(如:使用者的瀏覽器、訪問時間、訪問的地址等等),供網站提供者分析使用者瀏覽行為等,繼而來做推廣及提升網站的使用者體驗和質量。此功能由 ngx_http_log_module 模組負責。

訪問日誌引數:                 

Nginx 訪問日誌主要由下面兩個引數控制:

引數

說明

log_format

用來定義記錄日誌的格式(可定義多種日誌格式)

access_log

用來指定日誌檔案的路徑及使用何種日誌格式記錄日誌。

Nginx 日誌格式中預設的引數配置如下:

[[email protected] conf]# cat -n nginx.conf.default

    21      #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    22      #                  '$status $body_bytes_sent "$http_referer" '

    23      #                  '"$http_user_agent" "$http_x_forwarded_for"';

訪問日誌配置說明:

        其配置位置在 http 標籤內,其中 log_format 為日誌格式關鍵引數,不能變。main 是為日誌格式指定的標籤,記錄日誌時通過這個 main 標籤選擇指定的格式,其後所接的所有內容都是可以記錄的日誌資訊,具體見下表。注意,所有的日誌段以空格分隔,一行可以記錄多個,詳見下表:

Nginx 日誌變數

                    說明

$remote_addr

記錄訪問網站的客戶端地址

$remote_user

遠端客戶端使用者名稱稱

$time_local

記錄訪問時間與時區

$request

使用者的 http 請求起始行資訊

$status

http狀態碼,記錄請求返回的狀態

$body_bytes_sent

伺服器傳送給客戶端的響應 body 位元組數

$http_referer

記錄此次請求是從哪個連結訪問過來的,可根據referer進行防盜鏈設定

$http_user_agent

記錄客戶端訪問資訊,例如:瀏覽器、手機客戶端等

提示:在沒有特殊要求的情況下,採用預設的配置即可。更多資訊詳見官方文件。

2、Nginx 記錄日誌的預設引數配置如下:

 access_log  logs/access.log  main;

記錄日誌的 access_log 引數:

一般場景中, access_log  的引數都無需配置。

3、訪問日誌配置實戰:

從主配置檔案的備份檔案取出預設配置內容:

[[email protected] conf]# sed -n '21,23 s/#//gp' nginx.conf.default

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

把上述內容放到 nginx.conf 的 http 標籤的首部,如下:

[[email protected] conf]# cat -n  nginx.conf

     1  worker_processes  1;

     2  error_log logs/error.log error;

     3  events {

     4      worker_connections  1024;

     5  }

     6  http {

     7      include       mime.types;

     8      default_type  application/octet-stream;

     9      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    10                        '$status $body_bytes_sent "$http_referer" '

    11                        '"$http_user_agent" "$http_x_forwarded_for"';

    12      sendfile        on;

    13      keepalive_timeout  65;

    14      # nginx vhosts config

    15      include extra/www.conf;

    16      include extra/bbs.conf;

    17      include extra/blog.conf;

    18      include extra/status.conf;

    19  }

在每個虛擬主機裡進行配置,使其使用上述格式記錄使用者訪問日誌,以 www.etiantian.org 例:

[[email protected] conf]# vi extra/www.conf

[[email protected] conf]# cat extra/www.conf         

    server {

        listen       80;

        server_name  www.etiantian.org etiantian.org;

        location / {

            root   html/www;

            index  index.html index.htm;

        }  

        # access_log off;   #  表示不記錄日誌。   

         access_log  logs/access_www.log  main;    

}

提示:如果不指定日誌格式就會用預設的 combined 格式記錄日誌。

檢查語法,重新載入配置:

[[email protected] conf]# ../sbin/nginx -t

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[[email protected] conf]# ../sbin/nginx -s reload

[[email protected] conf]# curl www.etiantian.org

www.etiantian.org

[[email protected] conf]# ls -l ../log/access_www.log

ls: cannot access ../log/access_www.log: No such file or directory

[[email protected] conf]# ls -l ../logs/access_www.log

-rw-r--r-- 1 root root 192 Dec 21 17:07 ../logs/access_www.log

[[email protected] conf]# curl www.etiantian.org      

www.etiantian.org

[[email protected] conf]# tail -1 ../logs/access_www.log

192.168.136.143 - - [21/Dec/2017:17:08:52 +0800] "GET / HTTP/1.1" 200 18 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "-"

提示:黃色內容就是真實的訪問日誌內容,詳細說明見《Web P187~188》。

可以在記錄日誌引數中加上 buffer 和 flush 選項,這樣可以在高併發場景下提升網站訪問效能:

[[email protected] conf]# vi extra/www.conf

[[email protected] conf]# cat extra/www.conf

    server {

        listen       80;

        server_name  www.etiantian.org etiantian.org;

        location / {

            root   html/www;

            index  index.html index.htm;

        }

        # access_log  logs/access_www.log  main;    

         access_log  logs/access_www.log  main gzip buffer=32k flush=5s;

}

[[email protected] conf]# ../sbin/nginx -t  

[[email protected] conf]# ../sbin/nginx -s reload

Nginx 訪問日誌輪詢切割:

       預設情況 Nginx 會把所有的訪問日誌生成到一個指定的訪問日誌檔案 access.log 裡,但這樣一來,時間長了就會導致日誌個頭很大,不利於日誌的分析和處理,因此,有必要對 Nginx 日誌按天或按小時進行切割,使其分成不同的檔案儲存。這裡使用按天切割的方法:

具體切割指令碼如下:

[[email protected] scripts]# cat cut_nginx_log.sh

#!/bin/sh

Dateformat=`date +%Y%m%d`

Basedir="/application/nginx"

Nginxlogdir="$Basedir/logs"

Logname="access_www"

[ -d $Nginxlogdir ] && cd $Nginxlogdir||exit 1

[ -f ${Logname}.log ]||exit 1

/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log

$Basedir/sbin/nginx -s reload

提示:上面指令碼實現切割 Nginx 日誌的思想為將正在寫入的 Nginx 日誌(access_www.log)改名為帶日期的格式檔案(20171221_access_www.log),然後平滑重新載入 Nginx ,生成新的 Nginx 日誌(access_www.log)。

通過定時任務實現每天 00 點定時執行指令碼切割日誌:(crontb -e)

[[email protected] ~]# cat >>/var/spool/cron/root <<EOF    # 把上面指令碼放入定時任務。

> #cut nginx access log by zhanglei

> 00 00 * * * * /bin/sh /server/scripts/cut_nginx_log.sh &>/dev/null

> EOF

[[email protected] ~]# crontab -l

#cut nginx access log by zhanglei

00 00 * * * * /bin/sh /server/scripts/cut_nginx_log.sh &>/dev/null

[[email protected] ~]# cd /application/nginx/logs/

[[email protected] logs]# ll

total 20

-rw-r--r-- 1 root root  384 Dec 21 17:08 20171221_access_www.log   #  生成的切割訪問日誌。

-rw-r--r-- 1 root root 5431 Dec 21 01:16 access.log

-rw-r--r-- 1 root root    0 Dec 21 17:36 access_www.log

-rw-r--r-- 1 root root  240 Dec 21 17:36 error.log

-rw-r--r-- 1 root root    5 Dec 21 16:14 nginx.pid

[[email protected] logs]# cat 20171221_access_www.log    # 檢視切割的訪問日誌。

192.168.136.143 - - [21/Dec/2017:17:07:48 +0800] "GET / HTTP/1.1" 200 18 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "-"

192.168.136.143 - - [21/Dec/2017:17:08:52 +0800] "GET / HTTP/1.1" 200 18 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "-"          

提示:Nginx 常用的日誌收集及分析工具有 rsyslog 、awstats 、flume 、ELK、storm 等。

把另外兩個虛擬主機都配置訪問日誌格式並輪詢切割:

[[email protected] conf]# cat extra/bbs.conf   

    server {

        listen       80;

        server_name  bbs.etiantian.org;

        location / {

            root   html/bbs;

            index  index.html index.htm;

        }

        # access_log  logs/access_bbs.log  main;

        access_log  logs/access_bbs.log  main gzip buffer=32k flush=5s;

        # access_log off;    

}

[[email protected] conf]# cat extra/blog.conf    

        

    server {

        listen       80;

        server_name  blog.etiantian.org;

        location / {

            root   html/blog;

            index  index.html index.htm;

        }

        # access_log  logs/access_blog.log  main;

        access_log  logs/access_blog.log  main gzip buffer=32k flush=5s;

        # access_log off;

    }

實現的指令碼:

[[email protected] scripts]# cat cut_nginx_log.sh

#!/bin/sh

Dateformat=`date +%Y%m%d`

Basedir="/application/nginx"

Nginxlogdir="$Basedir/logs"

Logname="access_www"

[ -d $Nginxlogdir ] && cd $Nginxlogdir||exit 1

[ -f ${Logname}.log ]||exit 1

/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log

/bin/mv access_bbs.log ${Dateformat}_access_bbs.log

/bin/mv access_blog.log ${Dateformat}_access_blog.log

$Basedir/sbin/nginx -s reload

執行指令碼並檢視結果:

[[email protected] scripts]# /application/nginx/sbin/nginx -t

[[email protected] scripts]# /application/nginx/sbin/nginx -s reload

[[email protected] scripts]# sh cut_nginx_log.sh

[[email protected] conf]# cd  /application/nginx/logs/

[[email protected] logs]# ll

total 16

-rw-r--r-- 1 root root    0 Dec 21 15:20 20171221_access_bbs.log

-rw-r--r-- 1 root root    0 Dec 21 15:20 20171221_access_blog.log

-rw-r--r-- 1 root root    0 Dec 21 15:20 20171221_access_www.log

Nginx rewrite

什麼是 Nginx rewrite ?

       和 Apache 等 Web 軟體一樣,Nginx rewrite 的主要功能就是實現 URL 地址重寫。Nginx 的 rewrite 規則需要 PCRE 軟體的支援,即通過 Perl 相容正則表示式語法進行規則匹配。預設引數編譯時,Nginx 就會安裝支援 rewrite  的模組,但是也需要 PCRE 軟體的支援。

Nginx rewrite 語法:

       rewrite 指令語法:rewrite regex replacement [flag]

       應用位置:server、location、if

       rewrite 是實現 URL 重寫的關鍵指令,根據 regex (正則表示式)部分的內容,重定向到 replacement 部分,結尾是 flag 標記。例如:

       rewrite ^/(.*) http://www.etiantian.org/$1 permanent;

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

regex 常用正則表示式說明:見 << Web 叢集實戰 P 195 >>

regex 指令結尾的 flag 標記說明:

   flag 標記符號

                                             說明

last

本條規則匹配完成後,繼續向下匹配新的 location URI 規則 。

break

本條規則匹配完成即終止,不再匹配後面的任何規則。

redirect

返回 302 臨時重定向,瀏覽器位址列會顯示跳轉後的 URL 地址。

permanent

返回 301 永久重定向,瀏覽器位址列會顯示跳轉後的 URL 地址。

配置 Nginx rewrite 301 跳轉:

[[email protected] conf]# vi extra/www.conf

[[email protected] conf]# cat extra/www.conf   

    server {

     listen       80;

     server_name  etiantian.org;

     rewrite ^/(.*) http://www.etiantian.org/$1 permanent;

}

    server {

        listen       80;

        server_name  www.etiantian.org;     # 注意此處域名的別名要取消,避免衝突。

        location / {

            root   html/www;

            index  index.html index.htm;

        }

        # access_log  logs/access_www.log  main;    

         access_log  logs/access_www.log  main gzip buffer=32k flush=5s;

        # access_log off;

}

[[email protected] conf]# ../sbin/nginx -t      #  檢查語法。

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[[email protected] conf]# ../sbin/nginx -s reload   #  平滑生效。

[[email protected] conf]# curl -I etiantian.org  #  訪問 etiantian.org ,自動跳轉。   

HTTP/1.1 301 Moved Permanently   #  可以看到 301 跳轉。  

Server: nginx/1.6.3

Date: Thu, 21 Dec 2017 08:05:07 GMT

Content-Type: text/html

Content-Length: 184

Connection: keep-alive

Location: http://www.etiantian.org/   #  跳轉到指定域名。  

提示:域名及對應的 IP 需要解析。

Nginx rewrite 的企業應用場景:

 可以調整使用者瀏覽的 URL,使其看起來更規範,合乎併發及產品人員的需求;

 為了讓搜尋引擎收錄網站內容,提升使用者體驗,企業會將動態URL地址偽裝成靜態地址提供服務;

 網站換新域名後,讓舊域名的訪問跳轉到新的域名上,例如:讓京東的 360buy 換成 jd.com ;

 根據特殊變數、目錄、客戶端的資訊進行 URL 跳轉等。

實現不同域名的 URL 跳轉:

例:實現訪問http://blog.etiantian.org時自動跳轉到 http://www.etiantian.org/blog/oldboy.html 。

[[email protected] conf]# cat  extra/blog.conf   

    server {

        listen       80;

        server_name  blog.etiantian.org;

        location / {

            root   html/blog;

            index  index.html index.htm;

        }

        rewrite ^/(.*) http://www.etiantian.org/blog/oldboy.html break;

        # access_log  logs/access_blog.log  main;

        access_log  logs/access_blog.log  main gzip buffer=32k flush=5s;

        # access_log off;

    }

[[email protected] conf]# mkdir ../html/www/blog -p

[[email protected] conf]# echo oldboy >../html/www/blog/oldboy.html

[[email protected] conf]# ../sbin/nginx -t   

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[[email protected] conf]# ../sbin/nginx -s reload

[[email protected] conf]# curl -I blog.etiantian.org   #  302臨時重定向,跳轉至指定域名。  

HTTP/1.1 302 Moved Temporarily

Server: nginx/1.6.3

Date: Thu, 21 Dec 2017 09:32:20 GMT

Content-Type: text/html

Content-Length: 160

Connection: keep-alive

Location: http://www.etiantian.org/blog/oldboy.html   

在 Windows 瀏覽器訪問 http://blog.etiantian.org 結果:【如圖所示】