3W字長文講透Nginx高階用法

Nginx 狀態頁

基於nginx模塊ngx_http_auth_basic_module實現,在編譯安裝nginx的時候需要添加編譯參數--with-http_stub_status_module,否則配置完成之後監測會是提示語法錯誤。

查看是否加載了ngx_http_auth_basic_module模塊
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -V
nginx version: nginx/1.14.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --with-http_perl_module
[root@CentOS7 ~]#vim /apps/nginx/conf/nginx.conf
        location /nginx_status {
                stub_status;
                allow 192.168.36.0/24;
                deny all;
        }

[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload

訪問測試

[root@CentOS-Test ~]#curl 192.168.36.104/nginx_status
Active connections: 1
server accepts handled requests
 124 124 223  # 這三個數字分別對應accepts,handled,requests三個值
Reading: 0 Writing: 1 Waiting: 0

Active connections:當前處於活動狀態的客戶端連接數,包括連接等待空閒連接數。
accepts:統計總值,Nginx自啓動後已經接受的客戶端請求的總數。
handled:統計總值,Nginx自啓動後已經處理完成的客戶端請求的總數,通常等於accepts,除非有因
worker_connections限制等被拒絕的連接。
requests:統計總值,Nginx自啓動後客戶端發來的總的請求數。
Reading:當前狀態,正在讀取客戶端請求報文首部的連接的連接數。
Writing:當前狀態,正在向客戶端發送響應報文過程中的連接數。
Waiting:當前狀態,正在等待客戶端發出請求的空閒連接數,開啓 keep-alive的情況下,這個值等於active – (reading+writing),

Nginx第三方模塊

添加第三方模塊:echo-nginx-module
[root@CentOS7 ~]#yum install git -y
[root@CentOS7 ~]#git clone https://github.com/openresty/echo-nginx-module.git
[root@CentOS7 ~]#cd nginx-1.14.2/
[root@CentOS7 nginx-1.14.2]#./configure \  # 重新編譯安裝
> --prefix=/apps/nginx \
> --user=nginx --group=nginx \
> --with-http_ssl_module \
> --with-http_v2_module \
> --with-http_realip_module \
> --with-http_stub_status_module \
> --with-http_gzip_static_module \
> --with-pcre \
> --with-stream \
> --with-stream_ssl_module \
> --with-stream_realip_module \
> --with-http_perl_module \
> --add-module=/root/echo-nginx-module  # 添加echo模塊
[root@CentOS7 nginx-1.14.2]#make && make install  # make安裝
[root@CentOS7 ~]#vim /apps/nginx/conf.d/pc.conf
[root@CentOS7 ~]#cat /apps/nginx/conf.d/pc.conf
server {
  listen 80;
  server_name www.darius.com;
  error_log logs/www_darius_com_error.log;
  access_log logs/www_darius_com_access.log;
  location /main {
    index index.html;
    default_type text/html;
    echo_reset_timer;
    echo_location /sub1;
    echo_location /sub2;
    echo "took $echo_timer_elapsed sec for total.";
  }
  location /sub1 {
    echo_sleep 1;
    echo sub1;
  }
  location /sub2 {
    echo_sleep 1;
    echo sub2;
  }
}
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload

訪問測試

[root@CentOS7 ~]#curl www.darius.com/main
sub1
sub2
took 2.008 sec for total.

Nginx變量使用

nginx的變量可以在配置文件中引用,作爲功能判斷或者日誌等場景使用,變量可以分爲內置變量和自定義變量,內置變量是由nginx模塊自帶,通過變量可以獲取到衆多的與客戶端訪問相關的值。

內置變量

$remote_addr;
存放了客戶端的地址,注意是客戶端的公網IP,也就是一家人訪問一個網站,則會顯示爲路由器的公網IP。
$args;
變量中存放了URL中的指令,例如http://www.darius.com/main/index.do?
id=20190221&partner=search中的id=20190221&partner=search
$document_root;
保存了針對當前資源的請求的系統根目錄,如/apps/nginx/htm
$document_uri;
保存了當前請求中不包含指令的URI,注意是不包含請求的指令,比如
http://www.darius.com/main/index.do?id=20190221&partner=search會被定義爲/main/index.do
$host;
#存放了請求的host名稱。
$http_user_agent;
客戶端瀏覽器的詳細信息
$http_cookie;
客戶端的cookie信息
limit_rate 10240;
echo $limit_rate;
如果nginx服務器使用limit_rate配置了顯示網絡速率,則會顯示,如果沒有設置, 則顯示0
$remote_port;
客戶端請求Nginx服務器時隨機打開的端口,這是每個客戶端自己的端口
$remote_user;
已經經過Auth Basic Module驗證的用戶名
$request_body_file;
做反向代理時發給後端服務器的本地資源的名稱
$request_method;
請求資源的方式,GET/PUT/DELETE等
$request_filename;
當前請求的資源文件的路徑名稱,由root或alias指令與URI請求生成的文件絕對路徑,如/apps/nginx/html/main/index.html
$request_uri;
包含請求參數的原始URI,不包含主機名,如:/main/index.do?id=20190221&partner=search
$scheme;
請求的協議,如ftp,https,http等
$server_protocol;
保存了客戶端請求資源使用的協議的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
保存了服務器的IP地址
$server_name;
請求的服務器的主機名
$server_port;
請求的服務器的端口號

自定義變量

假如需要自定義變量名稱和值,使用指令set $variable value;,則方法如下:

set $name magedu;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";

範例

1、查看Nginx內置變量
[root@CentOS7 ~]#vim /apps/nginx/conf.d/pc.conf
[root@CentOS7 ~]#cat /apps/nginx/conf.d/pc.conf
server {
  listen 80;
  server_name www.darius.com;
  error_log logs/www_darius_com_error.log;
  access_log logs/www_darius_com_access.log;
  location /main {
    index index.html;
    default_type text/html;
    echo $request_uri;
  }
}
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload
[root@CentOS7 ~]#curl www.darius.com/main
/main
[root@CentOS7 ~]#curl www.darius.com/main/xxx
/main/xxx
2、查看Nginx自定義變量
[root@CentOS7 ~]#vim /apps/nginx/conf.d/pc.conf
[root@CentOS7 ~]#cat /apps/nginx/conf.d/pc.conf
server {
  listen 80;
  server_name www.darius.com;
  error_log logs/www_darius_com_error.log;
  access_log logs/www_darius_com_access.log;
  location /main {
    index index.html;
    default_type text/html;
    set $name Darius;
    echo $name;
  }
}
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload
[root@CentOS7 ~]#curl www.darius.com/main
Darius

自定義Nginx訪問日誌

訪問日誌是記錄客戶端即用戶的具體請求內容信息,全局配置模塊中的error_log是記錄nginx服務器運行時的日誌保存路徑和記錄日誌的level,因此有着本質的區別,而且Nginx的錯誤日誌一般只有一個,但是訪問日誌可以在不同server中定義多個,定義一個日誌需要使用access_log指定日誌的保存路徑,使用log_format指定日誌的格式,格式中定義要保存的具體日誌內容。

默認的日誌格式
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;
自定義json格式日誌
[root@CentOS7 ~]#vim /apps/nginx/conf/nginx.conf
    log_format access_json '{"@timestamp":"$time_iso8601",'
                           '"host":"$server_addr",'
                           '"clientip":"$remote_addr",'
                           '"size":$body_bytes_sent,'
                           '"responsetime":$request_time,'
                           '"upstreamtime":"$upstream_response_time",'
                           '"upstreamhost":"$upstream_addr",'
                           '"http_host":"$host",'
                           '"uri":"$uri",'
                           '"domain":"$host",'
                           '"xff":"$http_x_forwarded_for",'
                           '"referer":"$http_referer",'
                           '"tcp_xff":"$proxy_protocol_addr",'
                           '"http_user_agent":"$http_user_agent",'
                           '"status":"$status"}';
    access_log /apps/nginx/logs/access_json.log access_json;
重新加載nginx並訪問測試日誌格式
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload

[root@CentOS7 ~]#tail -f /apps/nginx/logs/access_json.log
{"@timestamp":"2019-05-30T18:58:23+08:00","host":"192.168.36.104","clientip":"192.168.36.110","size":15,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"192.168.36.104","uri":"/index.html","domain":"192.168.36.104","xff":"-","referer":"-","tcp_xff":"","http_user_agent":"curl/7.29.0","status":"200"}
python實現json格式的日誌訪問統計
[root@CentOS7 logs]#cat nginx_json.py
#!/usr/bin/env python
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":
            status_404.append(line.get)
        else:
            print("狀態碼 ERROR")
f.close()
print "狀態碼200的有--:",len(status_200)
print "狀態碼404的有--:",len(status_404)

保存日誌文件到指定路徑並進測試:
[root@CentOS7 ~]# python nginx_json.py
....
狀態碼200的有--: 403428
狀態碼404的有--: 125712

Nginx壓縮功能

Nginx支持對指定類型的文件進行壓縮然後再傳輸給客戶端,而且壓縮還可以設置壓縮比例,壓縮後的文件大小將比源文件顯著變小,這樣有助於降低出口帶寬的利用率,降低企業的IT支出,不過會佔用相應的CPU資源。Nginx對文件的壓縮功能是依賴於模塊ngx_http_gzip_module

啓用或禁用gzip壓縮,默認關閉
gzip on | off;

壓縮比由低到高從1到9,默認爲1
gzip_comp_level level;

禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";

gzip壓縮的最小文件,小於設置值的文件將不會壓縮
gzip_min_length 1k;

啓用壓縮功能時,協議的最小版本,默認HTTP/1.1
gzip_http_version 1.0 | 1.1;

指定Nginx服務需要向服務器申請的緩存空間的個數*大小,默認32 4k|16 8k;
gzip_buffers number size;

指明僅對哪些類型的資源執行壓縮操作;默認爲gzip_types text/html,不用顯示指定,否則出錯
gzip_types mime-type ...;

如果啓用壓縮,是否在響應報文首部插入“Vary: Accept-Encoding”
gzip_vary on | off;

配置文件修改

gzip on;
    gzip_comp_level 5;
    gzip_min_length 1;
    gzip_types text/plain application/javascript application/x-javascript text/cssapplication/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;

[root@CentOS7 ~]#/apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload

訪問測試

[root@CentOS-Test ~]#curl --head --compressed http://www.darius.com/test1.html
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 30 May 2019 11:26:49 GMT
Content-Type: text/html
Last-Modified: Thu, 30 May 2019 11:26:31 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"5cefbde7-720"
Content-Encoding: gzip

HTTPS 功能

Web網站的登錄頁面都是使用https加密傳輸的,加密數據以保障數據的安全,HTTPS能夠加密信息,以免敏感信息被第三方獲取,所以很多銀行網站或電子郵箱等等安全級別較高的服務都會採用HTTPS協議,HTTPS其實是有兩部分組成:HTTP + SSL / TLS,也就是在HTTP上又加了一層處理加密信息的模塊。服務端和客戶端的信息傳輸都會通過TLS進行加密,所以傳輸的數據都是加密後的數據。

https 實現過程

1.客戶端發起HTTPS請求:
客戶端訪問某個web端的https地址,一般都是443端口
2.服務端的配置:
採用https協議的服務器必須要有一套證書,可以通過一些組織申請,也可以自己製作,目前國內很多網站都自己做的,當你訪問一個網站的時候提示證書不可信任就表示證書是自己做的,證書就是一個公鑰和私鑰匙,就像一把鎖和鑰匙,正常情況下只有你的鑰匙可以打開你的鎖,你可以把這個送給別人讓他鎖住一個箱子,裏面放滿了錢或祕密,別人不知道里面放了什麼而且別人也打不開,只有你的鑰匙是可以打開的。
3.傳送證書:
服務端給客戶端傳遞證書,其實就是公鑰,裏面包含了很多信息,例如證書得到頒發機構、過期時間等等。
4.客戶端解析證書:
這部分工作是有客戶端完成的,首先回驗證公鑰的有效性,比如頒發機構、過期時間等等,如果發現異常則會彈出一個警告框提示證書可能存在問題,如果證書沒有問題就生成一個隨機值,然後用證書對該隨機值進行加密,就像2步驟所說把隨機值鎖起來,不讓別人看到。
5.傳送4步驟的加密數據:
就是將用證書加密後的隨機值傳遞給服務器,目的就是爲了讓服務器得到這個隨機值,以後客戶端和服務端的通信就可以通過這個隨機值進行加密解密了。
6.服務端解密信息:
服務端用私鑰解密5步驟加密後的隨機值之後,得到了客戶端傳過來的隨機值(私鑰),然後把內容通過該值進行對稱加密,對稱加密就是將信息和私鑰通過算法混合在一起,這樣除非你知道私鑰,不然是無法獲取其內部的內容,而正好客戶端和服務端都知道這個私鑰,所以只要機密算法夠複雜就可以保證數據的安全性。
7.傳輸加密後的信息:
服務端將用私鑰加密後的數據傳遞給客戶端,在客戶端可以被還原出原數據內容。
8.客戶端解密信息:
客戶端用之前生成的私鑰獲解密服務端傳遞過來的數據,由於數據一直是加密的,因此即使第三方獲取到數據也無法知道其詳細內容。

ssl 配置參數

nginx 的https 功能基於模塊ngx_http_ssl_module實現,因此如果是編譯安裝的nginx要使用參數ngx_http_ssl_module開啓ssl功能,但是作爲nginx的核心功能,yum安裝的nginx默認就是開啓的,編譯安裝的nginx需要指定編譯參數--with-http_ssl_module開啓

ssl on | off;
爲指定的虛擬主機配置是否啓用ssl功能,此功能在1.15.0廢棄,使用listen [ssl]替代。

ssl_certificate /path/to/file;
當前虛擬主機使用使用的公鑰文件,一般是crt文件

ssl_certificate_key /path/to/file;
當前虛擬主機使用的私鑰文件,一般是key文件

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支持ssl協議版本,早期爲ssl現在是TSL,默認爲後三個

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
配置ssl緩存

    off:關閉緩存
    none: 通知客戶端支持ssl session cache,但實際不支持
    builtin[:size]:使用OpenSSL內建緩存,爲每worker進程私有
    [shared:name:size]:在各worker之間使用一個共享的緩存,需要定義一個緩存名稱和緩存空間大小,一兆可以存儲4000個會話信息,多個虛擬主機可以使用相同的緩存名稱。

ssl_session_timeout time;  # 客戶端連接可以複用ssl session cache中緩存的有效時長,默認5m
自簽名證書創建
創建自簽名CA證書
[root@CentOS7 ~]#cd /apps/nginx/
[root@CentOS7 nginx]#mkdir certs
[root@CentOS7 nginx]# cd certs/
[root@CentOS7 certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt  # 自簽名CA證書
Generating a 4096 bit RSA private key
.............................................................................................................................................................................................................................................................................................................................................++
........................................................................................++
writing new prvate key to 'ca.key'

-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
lf you enter '.',the field will be left blamk

-----
Country Name (2 letter code) [XX]:CN  # 國家代碼
State or Province Name (full name) []:BeiJing  # 省份
Locality Name (eg, city) [Default City]:BeiJing  # 城市名稱
Organization Name (eg, company) [Default Company Ltd]:magedu.com  # 公司名稱
Organizational Unit Name (eg, section) []:magedu  # 部門
Common Name (eg, your name or your server's hostname) []:M36  # 通用名稱
Email Address []:  # 郵箱
[root@CentOS7 certs]#ll ca.crt
-rw-r--r-- 1 root root 2009 5月  30 19:34 ca.crt

創建自定義額key和csr文件

[root@CentOS7 certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.darius.com.key -out www.darius.com.csr
Generating a 4096 bit RSA private key
............++
..........................++
writing new prvate key to 'www.danrius.com.key'

-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
lf you enter '.',the field will be left blank.

-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:magedu.com
Organizational Unit Name (eg, section) []:magedu
Common Name (eg, your name or your server's hostname) []:M36
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@CentOS7 certs]#ll
總用量 16
-rw-r--r-- 1 root root 2009 5月  30 19:34 ca.crt
-rw-r--r-- 1 root root 3272 5月  30 19:34 ca.key
-rw-r--r-- 1 root root 1695 5月  30 19:38 www.darius.com.csr
-rw-r--r-- 1 root root 3272 5月  30 19:38 www.darius.com.key

證書籤發
[root@CentOS7 certs]#openssl x509 -req -days 3650 -in www.darius.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.darius.com.crt
Signature ok
subject=/C=CN/ST=BeiJing/L=BeiJing/O=magedu.com/OU=magedu/CN=M36
Getting CA Private Key

驗證證書內容
[root@CentOS7 certs]#openssl x509 -in www.darius.com.crt -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            fe:15:2c:1a:9d:a5:df:f5
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BeiJing, L=BeiJing, O=magedu.com, OU=magedu, CN=M36
        Validity
            Not Before: May 30 11:42:02 2019 GMT
            Not After : May 27 11:42:02 2029 GMT
        Subject: C=CN, ST=BeiJing, L=BeiJing, O=magedu.com, OU=magedu, CN=M36
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
修改Nginx配置文件
[root@CentOS7 ~]#vim /apps/nginx/conf.d/pc.conf
[root@CentOS7 ~]#cat /apps/nginx/conf.d/pc.conf
server {
  listen 80;
  listen 443 ssl;
  ssl_certificate /apps/nginx/certs/www.darius.com.crt;
  ssl_certificate_key /apps/nginx/certs/www.darius.com.key;
  ssl_session_cache shared:sslcache:20m;
  ssl_session_timeout 10m;
  server_name www.darius.com;
  error_log logs/www_darius_com_error.log;
  access_log logs/www_darius_com_access.log;
  location / {
    index index.html;
    root /data/nginx/html/pc;
  }
}

[root@CentOS7 ~]#/apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -s reload

訪問測試
3W字長文講透Nginx高階用法

關於favicon.ico

favicon.ico 文件是瀏覽器收藏網址時顯示的圖標,當客戶端使用瀏覽器問頁面時,瀏覽器會自己主動發起請求獲取頁面的favicon.ico文件,但是當瀏覽器請求的favicon.ico文件不存在時,服務器會記錄404日誌,而且瀏覽器也會顯示404報錯。

具體配置
一:服務器不記錄訪問日誌:
        # location = /favicon.ico {
        #   log_not_found off;
        #   access_log off;
        # }
二:將圖標保存到指定目錄訪問:
        # location ~ ^/favicon\.ico$ {
        location = /favicon.ico {
          root /data/nginx/images123;
        }

顯示效果
3W字長文講透Nginx高階用法

修改Nginx Server版本信息
修改Nginx源碼文件,此配置文件需要在nginx.conf的http中添加server_tokens  off;開啓nginx版本隱藏才能實現預期效果
[root@CentOS7 nginx-1.14.2]#vim src/http/ngx_http_header_filter_module.c
 49 static u_char ngx_http_server_string[] = "Server: Darius/10.0" CRLF;

停止Nginx服務,重新編譯Nginx
[root@CentOS7 nginx-1.14.2]#/apps/nginx/sbin/nginx -s stop
[root@CentOS7 nginx-1.14.2]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/root/echo-nginx-module

[root@CentOS7 nginx-1.14.2]#make && make ×××tall

啓動服務
[root@CentOS7 nginx-1.14.2]#/apps/nginx/sbin/nginx

檢測
[root@CentOS7-Test ~]#curl -I www.darius.com
HTTP/1.1 200 OK
Server: Darius/10.0

修改src/core/nginx.h文件無需開啓隱藏功能,起到修改版本信息的效果
[root@CentOS7 nginx-1.14.2]# vim src/core/nginx.h
 13 #define NGINX_VERSION      "10.0"
 14 #define NGINX_VER          "Darius/" NGINX_VERSION

3W字長文講透Nginx高階用法

Nginx Rewrite相關功能

Nginx服務器利用ngx_http_rewrite_module 模塊解析和處理rewrite請求,此功能依靠 PCRE(perl compatibler egularexpression),因此編譯之前要安裝PCRE庫,rewrite是nginx服務器的重要功能之一,用於實現URL的重寫,URL的重寫是非常有用的功能,比如它可以在我們改變網站結構之後,不需要客戶端修改原來的書籤,也無需其他網站修改我們的鏈接,就可以設置爲訪問,另外還可以在一定程度上提高網站的安全性。

if指令

用於條件匹配判斷,並根據條件判斷結果選擇不同的Nginx配置,可以配置在server或location塊中進行配置,Nginx的if語法僅能使用if做單次判斷,不支持使用if else或者if elif這樣的多重判斷

location /main {
    index index.html;
    default_type text/html;
    if ( $scheme = http ) {
      echo "if --> $scheme";
  }
  }
[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntaxis ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

檢測
[root@CentOS7-Test ~]#curl www.darius.com/main
if --> http

使用正則表達式對變量進行匹配,匹配成功時if指令認爲條件爲true,否則認爲false,變量與表達式之間使用以下符號鏈接

=:#比較變量和字符串是否相等,相等時if指令認爲該條件爲true,反之爲false。
!=: #比較變量和字符串是否不相等,不相等時if指令認爲條件爲true,反之爲false。
~:#表示在匹配過程中區分大小寫字符,(可以通過正則表達式匹配),滿足匹配條件爲真,不滿足爲假。
~*: #表示在匹配過程中不區分大小寫字符,(可以通過正則表達式匹配),滿足匹配條件爲真,不滿足問假。
!~:#區分大小寫不匹配,不滿足爲真,滿足爲假,不滿足爲真。
!~*:#爲不區分大小寫不匹配,滿足爲假,不滿足爲真。

-f 和 ! -f:判斷請求的文件是否存在和是否不存在
-d 和 ! -d: #判斷請求的目錄是否存在和是否不存在。
-x 和 ! -x: #判斷文件是否可執行和是否不可執行。
-e 和 ! -e: #判斷請求的文件或目錄是否存在和是否不存在(包括文件,目錄,軟鏈接)。

注:如果$變量的值爲空字符串或是以0開頭的任意字符串,則if指令認爲該條件爲false,其他條件爲true。
set指令

指定key並給其定義一個變量,變量可以調用Nginx內置變量賦值給key,另外set定義格式爲set $key $value,及無論是key還是value都要加$符號。

[root@CentOS7 conf.d]#vim pc.conf
  location /set {
    root index.html;
    default_type text/html;
    set $name Darius;
    echo $name;
    set $my_port $server_port;
    echo $my_port;
  }

[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntaxis ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

檢測
[root@CentOS7-Test ~]#curl www.darius.com/set
Darius
80
break指令

用於中斷當前相同作用域(location)中的其他Nginx配置,與該指令處於同一作用域的Nginx配置中,位於它前面的配置生效,位於後面的指令配置就不再生效了,Nginx服務器在根據配置處理請求的過程中遇到該指令的時候,回到上一層作用域繼續向下讀取配置,該指令可以在server塊和location塊以及if塊中使用,使用語法如下:

[root@CentOS7 conf.d]#vim pc.conf
  location /set {
    root index.html;
    default_type text/html;
    set $name Darius;
    echo $name;
    break;
    set $my_port $server_port;
    echo $my_port;
  }

[root@CentOS7 conf.d]#nginx -s reload

檢測
[root@CentOS7-Test ~]#curl www.darius.com/set
Darius
return指令

從nginx版本0.8.2開始支持,return用於完成對請求的處理,並直接向客戶端返回響應狀態碼,比如其可以指定重定向URL(對於特殊重定向狀態碼,301/302等) 或者是指定提示文本內容(對於特殊狀態碼403/500等),處於此指令後的所有配置都將不被執行,return可以在server、if和location塊進行配置

location /main {
    index index.html;
    default_type text/html;
    if ( $scheme = http ) {
      return 666 "not allow http"; # 可以是返回給客戶端指定的HTTP狀態碼、也可以是返回給客戶端的狀態碼及響應體內容(可以調用變量)、或者返回給客戶端URL地址
       echo "if-----> $scheme";  # return後面的將不再執行
  }

[root@CentOS7-Test ~]#curl www.darius.com/main
not allow http
[root@CentOS7-Test ~]#curl -I www.darius.com/main
HTTP/1.1 666
Server: Darius/10.0
Date: Sat, 01 Jun 2019 03:52:37 GMT
Content-Type: text/html
Content-Length: 14
Connection: keep-alive

rewrite_log指令
設置是否開啓記錄ngx_http_rewrite_module模塊日誌記錄到error_log日誌文件當中,可以配置在http、server、location或if當中,需要日誌級別爲notice

[root@CentOS7 conf.d]#vim ../conf/nginx.conf
error_log  logs/error.log  notice;  # 開啓錯誤日誌notice級別

[root@CentOS7 conf.d]#vim pc.conf  # 啓用rewrite_log指令
  location /set {
    root index.html;
    default_type text/html;
    set $name Darius;
    echo $name;
    rewrite_log on;
    break;
    set $my_port $server_port;
    echo $my_port;
  }

[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

訪問並驗證
[root@CentOS7 conf.d]#tail -f /apps/nginx/logs/*.log
==> /apps/nginx/logs/error.log <==
2019/06/01 12:01:46 [warn] 11234#0: *40 using uninitialized "my_port" variable, client: 192.168.36.110, server: www.darius.com, request: "GET /set/aaa HTTP/1.1", host: "www.darius.com"
rewrite指令

通過正則表達式的匹配來改變URI,可以同時存在一個或多個指令,按照順序依次對URI進行匹配,rewrite主要是針對用戶請求的URL或者是URI做具體處理

  URI(universal resource identifier):通用資源標識符,標識一個資源的路徑,可以不帶協議。
  URL(uniform resource location):統一資源定位符,是用於在Internet中描述資源的字符串,是URI的子集,主要包括傳輸協議(scheme)、主機(IP、端口號或者域名)和資源具體地址(目錄和文件名)等三部分,一般格式爲 scheme://主機名[:端口號][/資源路徑],如:http://www.a.com:8080/path/file/index.html就是一個URL路徑,URL必須帶訪問協議。
每個URL都是一個URI,但是URI不都是URL。
  例如:
  http://example.org/path/to/resource.txt #URI/URL
  ftp://example.org/resource.txt #URI/URL
  /absolute/path/to/resource.txt #URI
rewrite 四種flag使用介紹

redirect;
  臨時重定向,重寫完成後以臨時重定向方式直接返回重寫後生成的新URL給客戶端,由客戶端重新發起請求;使用相對路徑,或者http://或https://開頭,狀態碼:302
permanent;
   永久重定向,重寫完成後以永久重定向方式直接返回重寫後生成的新URL給客戶端,由客戶端重新發起請求,狀態碼:301
last;
  重寫完成後停止對當前URI在當前location中後續的其它重寫操作,而後對新的URL啓動新一輪重寫檢查,不建議在location中使用
break;
  重寫完成後停止對當前URL在當前location中後續的其它重寫操作,而後直接跳轉至重寫規則配置塊之後的其它配置;結束循環,建議在location中使用
注:其中前兩種是跳轉型的flag,後兩種是代理型,跳轉型是指有客戶端瀏覽器重新對新地址進行請求,代理型是在WEB服務器內部實現跳轉的。
rewrite域名永久重定向

[root@CentOS7 conf.d]#vim ../conf/nginx.conf
        location / {
            root   html;
            index  index.html index.htm;
            rewrite / http://www.darius.com permanent;  # 永久重定向301
            #rewrite / http://www.darius.com redirect;  # 臨時重定向302
        }

[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

重定向檢測
[root@CentOS7-Test ~]#curl 192.168.36.104
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@CentOS7-Test ~]#curl -L 192.168.36.104
www.darius.com
[root@CentOS7-Test ~]#curl -I 192.168.36.104
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 04:27:42 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: http://www.darius.com

3W字長文講透Nginx高階用法

rewrite 臨時重定向
[root@CentOS7-Test ~]#curl -I 192.168.36.104
HTTP/1.1 302 Moved Temporarily
Server: Darius/10.0
Date: Sat, 01 Jun 2019 04:28:32 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Location: http://www.darius.com

3W字長文講透Nginx高階用法

rewrite之URI重定向
location /last {
    rewrite ^/last/(.*) /test$1 last;
    return 888 "last";
  }
  location /break {
    rewrite ^/break/(.*) /test$1 break;
    return 666 "break";
  }
  location /test {
    return 999 "test";
  }

[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

 break不會跳轉到其他location中
[root@CentOS7-Test ~]#curl -L -i http://www.darius.com/break/index.html
HTTP/1.1 404 Not Found
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:12:04 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Vary: Accept-Encoding

<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

#last會跳轉到其他location中繼續執行匹配操作
[root@CentOS7-Test ~]#curl -L -i http://www.darius.com/last/index.html
HTTP/1.1 999
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:12:11 GMT
Content-Type: text/html
Content-Length: 4
Connection: keep-alive

test
rewrite實現頁面自動跳轉https
server {
  listen 80;
  listen 443 ssl;
  server_name www.darius.com;
  error_log /apps/nginx/logs/www_darius_com_error.log;
  access_log /apps/nginx/logs/www_darius_com_access.log access_json;
  ssl_certificate /apps/nginx/certs/www.darius.com.crt;
  ssl_certificate_key /apps/nginx/certs/www.darius.com.key;
  ssl_session_cache shared:sslcache:20m;
  ssl_session_timeout 10m;
  location / {
    root /data/nginx/html/pc;
    index index.html;
    if ( $scheme = http ){
      rewrite (.*) https://www.darius.com;
    }
  }
}
[root@CentOS7 conf.d]#nginx -s reload

訪問測試
[root@CentOS7-Test ~]#curl -L -i -k http://www.darius.com
HTTP/1.1 302 Moved Temporarily
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:29:34 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Location: https://www.darius.com

HTTP/1.1 200 OK
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:29:37 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Thu, 30 May 2019 03:06:03 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "5cef489b-7"
Accept-Ranges: bytes

pc web

3W字長文講透Nginx高階用法

判斷文件是否存在

當用戶訪問到公司網站時,輸入一個錯誤的URL,可以將用戶訪問的瀏覽頁面重定向到公司官網首頁上

  location / {
    root /data/nginx/html/pc;
    index index.html;
    if ( !-f $request_filename ){
      rewrite (.*) http://www.darius.com/index.html;
    }
  }

瀏覽測試
[root@CentOS7-Test ~]#curl -L -i http://www.darius.com/asdfg
HTTP/1.1 302 Moved Temporarily
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:56:26 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Location: http://www.darius.com/index.html

HTTP/1.1 200 OK
Server: Darius/10.0
Date: Sat, 01 Jun 2019 06:56:26 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Thu, 30 May 2019 03:06:03 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "5cef489b-7"
Accept-Ranges: bytes

pc web

Nginx防盜鏈

防盜鏈基於客戶端攜帶的referer實現,referer是記錄打開一個頁面之前記錄是從哪個頁面跳轉過來的標記信息,如果別人只鏈接了自己網站圖片或某個單獨的資源,而不是打開了網站的整個頁面,這就是盜鏈,referer就是之前的那個網站域名,正常的referer信息有以下幾種:

none:請求報文首部沒有referer首部,比如用戶直接在瀏覽器輸入域名訪問web網站,就沒有referer信息。
blocked:請求報文有referer首部,但無有效值,比如爲空。
server_names:referer首部中包含本主機名及即nginx 監聽的server_name。
arbitrary_string:自定義指定字符串,但可使用*作通配符。
regular expression:被指定的正則表達式模式匹配到的字符串,要使用~開頭,例如:
    ~.*\.magedu\.com。

盜鏈測試
3W字長文講透Nginx高階用法

[root@CentOS7 conf.d]#cat a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location / {
    root /data;
    index index.html;
  }
}
[root@CentOS7 conf.d]#cat /data/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>盜鏈頁面</title>
</head>
<body>
<a href="http://www.darius.com">測試盜鏈</a>
<img src="http://www.darius.com/logo.png">
</body>
</html>

3W字長文講透Nginx高階用法

被盜鏈日誌查看
[root@CentOS7 conf.d]#tail -f /apps/nginx/logs/*.log
==> /apps/nginx/logs/www_darius_com_access.log <==
{"@timestamp":"2019-06-01T15:21:30+08:00","host":"192.168.36.104","clientip":"192.168.36.1","size":0,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"www.darius.com","uri":"/logo.png","domain":"www.darius.com","xff":"-","referer":"http://www.a.com/","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:67.0) Gecko/20100101 Firefox/67.0","status":"304"}
開啓防盜鏈機制

基於訪問安全考慮,nginx支持通過ungx_http_referer_module模塊檢查訪問請求的referer信息是否有效實現防盜鏈功能

location / {
    root /data/nginx/html/pc;
    index index.html;
    valid_referers none blocked server_names *.magedu.com www.magedu.* api.online.test/v1/hostlist ~\.google\. ~\.baidu\.;
    if ($invalid_referer) {
      return 403;
    }
  }
[root@CentOS7 conf.d]#nginx -s reload

頁面訪問測試
3W字長文講透Nginx高階用法

Nginx反向代理

反向代理:反向代理也叫reverse proxy,指的是代理外網用戶的請求到內部的指定web服務器,並將數據返回給用戶的一種方式,這是用的比較多的一種方式。
Nginx除了可以在企業提供高性能的web服務之外,另外還可以將本身不具備的請求通過某種預定義的協議轉發至其它服務器處理,不同的協議就是Nginx服務器與其他服務器進行通信的一種規範,主要在不同的場景使用以下模塊實現不同的功能:

ngx_http_proxy_module: 將客戶端的請求以http協議轉發至指定服務器進行處理。
ngx_stream_proxy_module:將客戶端的請求以tcp協議轉發至指定服務器處理。
ngx_http_fastcgi_module:將客戶端對php的請求以fastcgi協議轉發至指定服務器助理。
ngx_http_uwsgi_module:將客戶端對Python的請求以uwsgi協議轉發至指定服務器處理。
##### Nginx http的反向代理實現
反向代理配置參數

1.proxy_pass; 用來設置將客戶端請求轉發給的後端服務器的主機,可以是主機名、IP地址:端口的方式,也可以代理到預先設置的主機羣組,需要模塊gx_http_upstream_module支持。

server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    proxy_pass http://192.168.36.110:80;  # 不帶斜線將訪問的/web,等於訪問後端服務器 http://192.168.36.103:80/web/index.html,即後端服務器配置的站點根目錄要有web目錄纔可以被訪問,這是一個追加/web到後端服務器。  帶斜線,等於訪問後端服務器的http://192.168.36.103:80/index.html 內容返回給客戶端  
    index index.html;
  }
}

訪問測試
[root@CentOS7 conf.d]#curl -L -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 08:24:33 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/

HTTP/1.1 200 OK
Date: Sat, 01 Jun 2019 08:24:31 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Sat, 25 May 2019 03:41:28 GMT
ETag: "19-589ae171491d6"
Accept-Ranges: bytes
Content-Length: 25
Content-Type: text/html; charset=UTF-8

<h1>Real Server 110</h1>

3W字長文講透Nginx高階用法
2.proxy_hide_header; 用於nginx作爲反向代理的時候,在返回給客戶端http響應的時候,隱藏後端服務版本相應頭部的信息,可以設置在http/server或location塊

[root@CentOS7 conf.d]#vim a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_hide_header Location;  # 若想隱藏多個head頭部信息需要再次定義proxy_hide_header,不支持在後面接着寫
  }
}

[root@CentOS7 conf.d]#nginx -s reload
[root@CentOS7 conf.d]#curl -L -I http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 08:30:47 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive

3.proxy_pass_request_body on | off; 是否向後端服務器發送HTTP包體部分,可以設置在http/server或location塊,默認即爲開啓
4.proxy_pass_request_headers on | off; 是否將客戶端的請求頭部轉發給後端服務器,可以設置在http/server或location塊,默認即爲開啓
5.proxy_set_header; 可以更改或添加客戶端的請求頭部信息內容並轉發至後端服務器,比如在後端服務器想要獲取客戶端的真實IP的時候,就要更改每一個報文的頭部,如下:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header HOST $remote_addr;
 添加HOST到報文頭部,如果客戶端爲NAT上網那麼其值爲客戶端的共用的公網IP地址。

6.proxy_hide_header field; 用於隱藏後端服務器特定的響應首部,默認nginx在響應報文中不傳遞後端服務器的首部字段Date, Server, XPad, X-Accel等
7.proxy_connect_timeout time; 配置nginx服務器與後端服務器嘗試建立連接的超時時間,默認爲60秒

proxy_connect_timeout 60s;
60s爲自定義nginx與後端服務器建立連接的超時時間

8.proxy_read_time time; 配置nginx服務器向後端服務器或服務器組發起read請求後,等待的超時時間,默認60s

proxy_send_time time;
 配置nginx項後端服務器或服務器組發起write請求後,等待的超時時間,默認60s

9.proxy_http_version 1.0; 用於設置nginx提供代理服務的HTTP協議的版本,默認http 1.0
10.proxy_ignore_client_abort off; 當客戶端網絡中斷請求時,nginx服務器中斷其對後端服務器的請求。即如果此項設置爲on開啓,則服務器會忽略客戶端中斷並一直等着代理服務執行返回,如果設置爲off,則客戶端中斷後Nginx也會中斷客戶端請求並立即記錄499日誌,默認爲off。
11.proxy_headers_hash_bucket_size 64; 當配置了 proxy_hide_header和proxy_set_header的時候,用於設置nginx保存HTTP報文頭的hash表的上限。
12.proxy_headers_hash_max_size 512; 設置proxy_headers_hash_bucket_size的最大可用空間
13.server_names_hash_bucket_size 512; server_name hash表申請空間大小
14.server_names_hash_max_szie 512; 設置服務器名稱hash表的上限大小

反向代理--緩存功能

1.proxy_cache zone | off; 默認off 指明調用的緩存,或關閉緩存機制
2.proxy_cache_key string; 緩存中用於“鍵”的內容,默認值:proxy_cache_key $scheme$proxy_host$request_uri;
3.proxy_cache_valid [code ...] time; 定義對特定響應碼的響應內容的緩存時長,定義在http{...}中
示例

 調用緩存功能,需要定義在相應的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 10m;  # 對200、302類響應碼緩存10分鐘
proxy_cache_valid 404 1m;   # 對404類響應碼緩存1分鐘

4.proxy_cache_path; 定義可用於proxy功能的緩存;

使用方法:

proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number]
[purger_sleep=time] [purger_threshold=time];

示例:在http配置定義緩存信息
proxy_cache_path /var/cache/nginx/proxy_cache # 定義緩存保存路徑,proxy_cache會自動創

levels=1:2:2; # 定義緩存目錄結構層次,1:2:2可以生成2^4x2^8x2^8=1048576個目錄
keys_zone=proxycache:20m; # 指內存中緩存的大小,主要用於存放key和metadata(如:使用次數)
inactive=120s; # 緩存有效時間
max_size=1g; # 最大磁盤佔用空間,磁盤存入文件內容的緩存空間最大值

5. proxy_cache_use_stale; 在被代理的後端服務器出現哪種情況下,可直接使用過期的緩存響應客戶端
bash
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默認是off

6.proxy_cache_methods GET | HEAD | POST ...; 對哪些客戶端請求方法對應的響應進行緩存,GET和HEAD方法總是被緩存
7.proxy_set_header field value; 設定發往後端主機的請求報文的請求首部的值

Context: http, server, location
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
請求報文的標準格式如下:
X-Forwarded-For: client1, proxy1, proxy2

緩存配置

[root@CentOS7 conf.d]#vim ../conf/nginx.conf  # 配置在nginx.conf http配置段
    proxy_cache_path /data/nginx/proxycache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;

[root@CentOS7 conf.d]#cat a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {    # 要緩存的URL或者放在server配置項對所有URL都進行緩存
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_hide_header Location;
    proxy_hide_header Connection;
    proxy_set_header clientip $remote_addr;
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 10m;
    proxy_cache_valid any 1m;
  }
}
[root@CentOS7 conf.d]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 conf.d]#nginx -s reload

訪問驗證

[root@CentOS7 conf.d]#curl -L http://www.a.com/app
[root@CentOS7 conf.d]#ab -n 2000 -c 200 http://www.a.com/app
Total transferred:      822000 bytes
HTML transferred:       468000 bytes
Requests per second:    9413.58 [#/sec] (mean)
Time per request:       21.246 [ms] (mean)
Time per request:       0.106 [ms] (mean, across all concurrent requests)
Transfer rate:          3778.30 [Kbytes/sec] received

 緩存路徑結構及文件大小
[root@CentOS7 conf.d]#tree /data/nginx/proxycache/
/data/nginx/proxycache/
├── 2
│   └── e
│       └── 8
└── 7
    └── 5
        └── b
            └── 606c5106afffe9fd4f2021504afe7b57

6 directories, 1 file

驗證文件內容
[root@CentOS7 conf.d]#head -n100 /data/nginx/proxycache/7/5/b/606c5106afffe9fd4f2021504afe7b57
HTTP/1.1 200 OK
Date: Sat, 01 Jun 2019 09:51:06 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Sat, 01 Jun 2019 09:50:35 GMT
ETag: "1388-58a4010131b0d"
Accept-Ranges: bytes
Content-Length: 5000
Connection: close
Content-Type: text/html; charset=UTF-8
添加自定義頭部信息

nginx基於模塊ngx_http_headers_module可以實現對頭部報文添加指定的key與值

 添加自定義首部,如下:
add_header name value [always];
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
add_trailer name value [always];
添加自定義響應信息的尾部, 1.13.2版後支持
Nginx配置
[root@CentOS7 conf.d]#cat a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location /app {
    index index.html;
    proxy_pass http://192.168.36.110:80;
    proxy_set_header clientip $remote_addr;
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 10m;
    proxy_cache_valid any 1m;
    add_header X-Via $server_addr;
    add_header X-Cache $upstream_cache_status;
    add_header X-Accel $server_name;
  }
}
[root@CentOS7 conf.d]#nginx -s reload

[root@CentOS7 conf.d]#curl -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 10:12:16 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/
X-Via: 192.168.36.104
X-Cache: MISS  # 第一次訪問沒有使用緩存,再次進行訪問測試
X-Accel: www.a.com

[root@CentOS7 conf.d]#curl -i http://www.a.com/app
HTTP/1.1 301 Moved Permanently
Server: Darius/10.0
Date: Sat, 01 Jun 2019 10:12:18 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Connection: keep-alive
Location: http://192.168.36.110/app/
X-Via: 192.168.36.104
X-Cache: HIT   # 第二次訪問命中緩存
X-Accel: www.a.com
自定義頭部

3W字長文講透Nginx高階用法

第二次訪問命中緩存

3W字長文講透Nginx高階用法

Nginx http反向代理高級應用

Nginx可以基於ngx_http_upstream_module模塊提供服務器分組轉發、權重分配、狀態監測、調度算法等高級功能

http upstream 配置參數
upstream name {

} 
 自定義一組服務器,配置在http內

server address [parameters];
 配置一個後端web服務器,配置在upstream內,至少要有一個server服務器配置。
 server支持的parameters如下:
weight=number # 設置權重,默認爲1。
max_conns=number # 給當前server設置最大活動鏈接數,默認爲0表示沒有限制。
max_fails=number # 對後端服務器連續監測失敗多少次就標記爲不可用。
fail_timeout=time # 對後端服務器的單次監測超時時間,默認爲10秒。
backup # 設置爲備份服務器,當所有服務器不可用時將重新啓用次服務器。
down # 標記爲down狀態。
resolve # 當server定義的是主機名的時候,當A記錄發生變化會自動應用新IP而不用重啓Nginx。

hash KEY consistent;
 基於指定key做hash計算,使用consistent參數,將使用ketama一致性hash算法,適用於後端是Cache服務器(如varnish)時使用,consistent定義使用一致性hash運算,一致性hash基於取模運算。

 所謂取模運算,就是計算兩個數相除之後的餘數,比如10%7=3, 7%4=3
hash $request_uri consistent; # 基於用戶請求的uri做hash

ip_hash; # 源地址hash調度方法,基於的客戶端的remote_addr(源地址)做hash計算,以實現會話保持

least_conn; # 最少連接調度算法,優先將客戶端請求調度到當前連接最少的後端服務器
多臺web服務器實現反向代理
[root@CentOS7 conf.d]#vim ../conf/nginx.conf
    upstream app1 {
      #hash $request_uri consistent;
      #ip_hash;  # 指定ip_hash算法,根據session調度到同一臺後端主機上,當此臺主機宕機,則強制切換到另一臺存活的主機上
      #least_conn;
      server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3;  # 後端服務器狀態監測:fail_timeout連續檢測多少次失敗,max_fails檢測時長
      server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3;
      server 192.168.36.101:80 weight=1 fail_timeout=5s max_fails=3 backup;  # 備用服務器,當其餘反向代理服務器宕機,啓用備用服務器
    }
[root@CentOS7 conf.d]#vim a.conf
server {
  listen 80;
  charset utf-8;
  server_name www.a.com;
  location / {
    index index.html;
    root /data/nginx/html/pc;
  }
  location /app {
    index index.html;
    proxy_pass http://app1;
  }
}
[root@CentOS7 conf.d]#nginx -s reload

訪問測試
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.110
192.168.36.106
192.168.36.110
192.168.36.106
啓用ip_hash算法
[root@CentOS7 conf.d]#vim ../conf/nginx.conf
    upstream app1 {
      #hash $request_uri consistent;
      #least_conn;
      server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3;
      server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3;
      ip_hash;
    }
[root@CentOS7 conf.d]#nginx -s reload

訪問測試:
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106

宕機測試
[root@CentOS7 conf.d]#while true;do curl  http://www.a.com/app/index.html;sleep 0.5;done
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.106
192.168.36.110   # 請求被強制切換到存活主機上
192.168.36.110
....
192.168.36.106  # 當修復好宕機主機重新工作,請求將重新回到原來的主機上
192.168.36.106
192.168.36.106
Nginx動靜分離
upstream web {
    server  192.168.36.1 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.2 weight=1 max_fails=2  fail_timeout=2;
} 

upstream image  {
    server  192.168.36.3 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.4 weight=1 max_fails=2  fail_timeout=2;
} 

upstream php {
    server  192.168.36.5 weight=1 max_fails=2  fail_timeout=2;
    server  192.168.36.6 weight=1 max_fails=2  fail_timeout=2;
} 

location  /{
    root html/web;
    index  index.php index.html;
}

location ~* \.php$ {
    fastcgi_proxy  http://php;
}

location ~* "\.(.jpg|png|jpeg|gif)" {
    proxy_pass http://image;
}

Nginx Tcp負載均衡

Nginx在1.9.0版本開始支持tcp模式的負載均衡,在1.9.13版本開始支持udp協議的負載,udp主要用於DNS的域名解析,其配置方式和指令和http 代理類似,其基於ngx_stream_proxy_module模塊實現tcp負載,另外基於模塊ngx_stream_upstream_module實現後端服務器分組轉發、權重分配、狀態監測、調度算法等高級功能。

Tcp負載均衡配置參數
stream { #定義stream
  upstream backend { #定義後端服務器
    hash $remote_addr consistent; #定義調度算法
    server backend1.example.com:12345 weight=5; #定義具體server
    server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
  } 
  upstream dns { #定義後端服務器
    server 192.168.0.1:53535; #定義具體server
    server dns.example.com:53;
  } 
  server { #定義server
    listen 12345; #監聽IP:PORT
    proxy_connect_timeout 1s; #連接超時時間
    proxy_timeout 3s; #轉發超時時間
    proxy_pass backend; #轉發到具體服務器組
  } 
  server {
    listen 127.0.0.1:53 udp reuseport;
    proxy_timeout 20s;
    proxy_pass dns;
  } 
  server {
    listen [::1]:12345;
    proxy_pass unix:/tmp/stream.socket;
  }
}
負載均衡實驗環境

3W字長文講透Nginx高階用法

基於Redis的負載均衡實例

安裝並配置Redis服務
[root@CentOS7-1 ~]#yum install -y redis
[root@CentOS7-1 ~]#vim /etc/redis.conf
[root@CentOS7-1 ~]#egrep "^bind" /etc/redis.conf
bind 0.0.0.0
[root@CentOS7-1 ~]#systemctl start redis
[root@CentOS7-1 ~]#systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
[root@CentOS7-1 ~]#ss -ntl | grep 6379   # Redis基於6379端口進行工作
LISTEN     0      128          *:6379                     *:*
Nginx配置
[root@CentOS7 ~]#mkdir /apps/nginx/tcp
[root@CentOS7 ~]#cd /apps/nginx/tcp/
[root@CentOS7 tcp]#vim tcp.conf
stream {
  upstream redis_server {
    server 192.168.36.110:6379 max_fails=3 fail_timeout=30s;
  }
  server {
    listen 192.168.36.104:6379;
    proxy_connect_timeout 3s;
    proxy_timeout 3s;
    proxy_pass redis_server;
  }
}

[root@CentOS7 tcp]#vim ../conf/nginx.conf
include /apps/nginx/tcp/tcp.conf;   # 注意此處的include與http模塊平級,建議寫在http模塊上方

[root@CentOS7 tcp]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 tcp]#nginx -s reload

查看6379端口是否開啓
[root@CentOS7 tcp]#ss -ntl | grep 6379
LISTEN     0      128    192.168.36.104:6379                     *:*

測試通過Nginx負載連接Redis
[root@CentOS7-1 ~]#redis-cli -h 192.168.36.104
192.168.36.104:6379> set name darius
OK
192.168.36.104:6379> get name
"darius"
192.168.36.104:6379>

基於Mysql的負載均衡實例

服務器安裝Mariadb
[root@CentOS7-1 ~]#yum install -y mariadb mariadb-server
[root@CentOS7-1 ~]#systemctl start mariadb   # 啓動mariadb數據庫服務
[root@CentOS7-1 ~]#systemctl enable mariadb   # 開機自啓動數據庫服務
[root@CentOS7-1 ~]#ss -ntl | grep 3306   # 檢查端口是否啓動
LISTEN     0      50           *:3306                     *:*

Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@CentOS7-1 ~]#mysql_secure_installation   # 對數據庫進行安全加固

 對數據庫進行授權操作
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.36.%' IDENTIFIED BY 'centos';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Nginx配置

[root@CentOS7 tcp]#vim tcp.conf
stream {
  upstream mysql_server {
    least_conn;
    server 192.168.36.110:3306 max_fails=3 fail_timeout=30s;
  }
  server {
    listen 192.168.36.104:3306;
    proxy_connect_timeout 3s;
    proxy_timeout 3s;
    proxy_pass mysql_server;
  }
}
[root@CentOS7 tcp]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 tcp]#nginx -s reload

 對負載端口進行檢查
[root@CentOS7 tcp]#ss -ntl | grep 3306
LISTEN     0      128    192.168.36.104:3306                     *:*

####測試通過nginx負載連接Mysql

[root@CentOS7-1 ~]#mysql -uroot -pcentos -h 192.168.36.104
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 16
Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE Darius;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| Darius             |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

MariaDB [(none)]>

3W字長文講透Nginx高階用法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章