天天看點

Nginx 的 6 大應用場景!

Nginx 的 6 大應用場景!

今天給大家分享一下關于Nginx的6大常見運用場景,學會之後就能直接上手用起來~~~

一、HTTP伺服器

Nginx本身也是一個靜态資源的伺服器,當隻有靜态資源的時候,就可以使用Nginx來做伺服器,如果一個網站隻是靜态頁面的話,那麼就可以通過這種方式來實作部署。

1、 首先在文檔根目錄​

​Docroot(/usr/local/var/www)​

​下建立html目錄, 然後在html中放一個test.html;

Nginx 的 6 大應用場景!

2、 配置​

​nginx.conf​

​中的server

user mengday staff;

http {
    server {
        listen       80;
        server_name  localhost;
        client_max_body_size 1024M;

        # 預設location
        location / {
            root   /usr/local/var/www/html;
            index  index.html index.htm;
        }
    }
}      

3、通路測試

  • ​http://localhost/​

    ​指向

    /usr/local/var/www/index.html

    , index.html是安裝nginx自帶的html
  • ​http://localhost/test.html​

    ​指向

    /usr/local/var/www/html/test.html

注意:如果通路圖檔出現403 Forbidden錯誤,可能是因為nginx.conf 的第一行user配置不對,預設是#user nobody;是注釋的,linux下改成user root; macos下改成user 使用者名 所在組; 然後重新加載配置檔案或者重新開機,再試一下就可以了, 使用者名可以通過who am i 指令來檢視。

4、指令簡介

  • server : 用于定義服務,http中可以有多個server塊
  • listen : 指定伺服器偵聽請求的IP位址和端口,如果省略位址,伺服器将偵聽所有位址,如果省略端口,則使用标準端口
  • server_name : 服務名稱,用于配置域名
  • location : 用于配置映射路徑uri對應的配置,一個server中可以有多個location, location後面跟一個uri,可以是一個正規表達式, / 表示比對任意路徑, 當用戶端通路的路徑滿足這個uri時就會執行location塊裡面的代碼
  • root : 根路徑,當通路

    http://localhost/test.html

    ,“/test.html”會比對到”/”uri, 找到root為

    /usr/local/var/www/html

    ,使用者通路的資源實體位址=

    root + uri = /usr/local/var/www/html + /test.html=/usr/local/var/www/html/test.html

  • index : 設定首頁,當隻通路

    server_name

    時後面不跟任何路徑是不走root直接走index指令的;如果通路路徑中沒有指定具體的檔案,則傳回index設定的資源,如果通路

    http://localhost/html/

    則預設傳回index.html

5、location uri正規表達式

  • ​.​

    ​:比對除換行符以外的任意字元
  • ​?​

    ​:重複0次或1次
  • ​+​

    ​:重複1次或更多次
  • ​*​

    ​:重複0次或更多次
  • ​\d​

    ​:比對數字
  • ​^​

    ​:比對字元串的開始
  • ​$​

    ​:比對字元串的結束
  • ​{n}​

    ​:重複n次
  • ​{n,}​

    ​:重複n次或更多次
  • ​[c]​

    ​:比對單個字元c
  • ​[a-z]​

    ​:比對a-z小寫字母的任意一個
  • ​(a|b|c)​

    ​: 屬線表示比對任意一種情況,每種情況使用豎線分隔,一般使用小括号括包覆,比對符合a字元 或是b字元 或是c字元的字元串
  • ​\​

    ​反斜杠:用于轉義特殊字元

小括号()之間比對的内容,可以在後面通過​

​$1​

​來引用,​

​$2​

​表示的是前面第二個()裡的内容。正則裡面容易讓人困惑的是​

​\​

​轉義特殊字元。

二、靜态伺服器

在公司中經常會遇到靜态伺服器,通常會提供一個上傳的功能,其他應用如果需要靜态資源就從該靜态伺服器中擷取。

1、在​

​/usr/local/var/www​

​下分别建立images和img目錄,分别在每個目錄下放一張​

​test.jpg​

http {
    server {
        listen       80;
        server_name  localhost;


        set $doc_root /usr/local/var/www;

        # 預設location
        location / {
            root   /usr/local/var/www/html;
            index  index.html index.htm;
        }

        location ^~ /images/ {
            root $doc_root;
       }

       location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
           root $doc_root/img;
       }
    }
}      

自定義變量使用set指令,文法 set 變量名值;引用使用變量名值;引用使用變量名; 這裡自定義了doc_root變量。

靜态伺服器location的映射一般有兩種方式:

  • 使用路徑,如 /images/ 一般圖檔都會放在某個圖檔目錄下,
  • 使用字尾,如 .jpg、.png 等字尾比對模式

通路​

​http://localhost/test.jpg​

​會映射到​

​$doc_root/img​

通路​

​http://localhost/images/test.jpg​

​當同一個路徑滿足多個location時,優先比對優先級高的location,由于​

​^~​

​的優先級大于​

​~​

​, 是以會走​

​/images/​

​對應的location

常見的location路徑映射路徑有以下幾種:

  • ​=​

    ​  進行普通字元精确比對。也就是完全比對。
  • ​^~​

    ​  字首比對。如果比對成功,則不再比對其他location。
  • ​~​

    ​  表示執行一個正則比對,區分大小寫
  • ​~*​

    ​  表示執行一個正則比對,不區分大小寫
  • ​/xxx/​

    ​正常字元串路徑比對
  • ​/​

    ​  通用比對,任何請求都會比對到

location優先級

當一個路徑比對多個location時究竟哪個location能比對到時有優先級順序的,而優先級的順序于location值的表達式類型有關,和在配置檔案中的先後順序無關。相同類型的表達式,字元串長的會優先比對。推薦:Java面試題大全

以下是按優先級排列說明:

  • 等号類型(=)的優先級最高。一旦比對成功,則不再查找其他比對項,停止搜尋。
  • ​^~​

    ​類型表達式,不屬于正規表達式。一旦比對成功,則不再查找其他比對項,停止搜尋。
  • 正規表達式類型(

    ~ ~*

    )的優先級次之。如果有多個location的正則能比對的話,則使用正規表達式最長的那個。
  • 正常字元串比對類型。按字首比對。
  • / 通用比對,如果沒有比對到,就比對通用的

優先級搜尋問題:不同類型的location映射決定是否繼續向下搜尋

  • 等号類型、

    ^~

    類型:一旦比對上就停止搜尋了,不會再比對其他location了
  • 正規表達式類型(

    ~ ~*

    ),正常字元串比對類型

    /xxx/

    : 比對到之後,還會繼續搜尋其他其它location,直到找到優先級最高的,或者找到第一種情況而停止搜尋

location優先級從高到底:

(​

​location =​

​) > (​

​location 完整路徑​

​) > (​

​location ^~ 路徑​

​) > (​

​location ~,~* 正則順序​

​) > (​

​location 部分起始路徑​

​) > (​

​/​

​)

location = / {
    # 精确比對/,主機名後面不能帶任何字元串 /
    [ configuration A ]
}
location / {
    # 比對所有以 / 開頭的請求。
    # 但是如果有更長的同類型的表達式,則選擇更長的表達式。
    # 如果有正規表達式可以比對,則優先比對正規表達式。
    [ configuration B ]
}
location /documents/ {
    # 比對所有以 /documents/ 開頭的請求,比對符合以後,還要繼續往下搜尋。
    # 但是如果有更長的同類型的表達式,則選擇更長的表達式。
    # 如果有正規表達式可以比對,則優先比對正規表達式。
    [ configuration C ]
}
location ^~ /images/ {
    # 比對所有以 /images/ 開頭的表達式,如果比對成功,則停止比對查找,停止搜尋。
    # 是以,即便有符合的正規表達式location,也不會被使用
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    # 比對所有以 gif jpg jpeg結尾的請求。
    # 但是 以 /images/開頭的請求,将使用 Configuration D,D具有更高的優先級
    [ configuration E ]
}

location /images/ {
    # 字元比對到 /images/,還會繼續往下搜尋
    [ configuration F ]
}


location = /test.htm {
    root   /usr/local/var/www/htm;
    index  index.htm;
}      

注意:location的優先級與location配置的位置無關。另外,Nginx 系列面試題和答案全部整理好了,微信搜尋網際網路架構師,在背景發送:2T,可以線上閱讀。

三、反向代理

反向代理應該是Nginx使用最多的功能了,反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連接配接請求,然後将請求轉發給内部網絡上的伺服器,并将從伺服器上得到的結果傳回給internet上請求連接配接的用戶端,此時代理伺服器對外就表現為一個反向代理伺服器。

簡單來說就是真實的伺服器不能直接被外部網絡通路,是以需要一台代理伺服器,而代理伺服器能被外部網絡通路的同時又跟真實伺服器在同一個網絡環境,當然也可能是同一台伺服器,端口不同而已。

反向代理通過​

​proxy_pass​

​指令來實作。

啟動一個Java Web項目,端口号為8081,可以利用 Spring Boot 快速搭建一個項目:https://github.com/vehang/ehang-spring-boot

server {
    listen       80;
    server_name  localhost;

    location / {
        proxy_pass http://localhost:8081;
        proxy_set_header Host $host:$server_port;
        # 設定使用者ip位址
         proxy_set_header X-Forwarded-For $remote_addr;
         # 當請求伺服器出錯去尋找其他伺服器
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; 
    }

}      

當我們通路localhost的時候,就相當于通路​

​localhost:8081​

​了。

四、負載均衡

負載均衡也是Nginx常用的一個功能,負載均衡其意思就是分攤到多個操作單元上進行執行,例如Web伺服器、FTP伺服器、企業關鍵應用伺服器和其它關鍵任務伺服器等,進而共同完成工作任務。

簡單而言就是當有2台或以上伺服器時,根據規則随機的将請求分發到指定的伺服器上處理,負載均衡配置一般都需要同時配置反向代理,通過反向代理跳轉到負載均衡。而Nginx目前支援自帶3種負載均衡政策,還有2種常用的第三方政策。

負載均衡通過upstream指令來實作。

1. RR(round robin :輪詢 預設)

每個請求按時間順序逐一配置設定到不同的後端伺服器,也就是說第一次請求配置設定到第一台伺服器上,第二次請求配置設定到第二台伺服器上,如果隻有兩台伺服器,第三次請求繼續配置設定到第一台上,這樣循環輪詢下去,也就是伺服器接收請求的比例是 1:1, 如果後端伺服器down掉,能自動剔除。輪詢是預設配置,不需要太多的配置

同一個項目分别使用8081和8082端口啟動項目

upstream web_servers {  
   server localhost:8081;  
   server localhost:8082;  
}

server {
    listen       80;
    server_name  localhost;
    #access_log  logs/host.access.log  main;


    location / {
        proxy_pass http://web_servers;
        # 必須指定Header Host
        proxy_set_header Host $host:$server_port;
    }
 }      

通路位址仍然可以獲得響應​

​http://localhost/api/user/login?username=zhangsan&password=111111​

​,這種方式是輪詢的

2. 權重

指定輪詢幾率,weight和通路比率成正比, 也就是伺服器接收請求的比例就是各自配置的weight的比例,用于後端伺服器性能不均的情況,比如伺服器性能差點就少接收點請求,伺服器性能好點就多處理點請求。

upstream test {
    server localhost:8081 weight=1;
    server localhost:8082 weight=3;
    server localhost:8083 weight=4 backup;
}      

示例是4次請求隻有一次被配置設定到8081上,其他3次配置設定到8082上。backup是指熱備,隻有當8081和8082都當機的情況下才走8083

3. ip_hash

上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個伺服器,當我們的程式不是無狀态的時候(采用了session儲存資料),這時候就有一個很大的很問題了,比如把登入資訊儲存到了session中,那麼跳轉到另外一台伺服器的時候就需要重新登入了,是以很多時候我們需要一個客戶隻通路一個伺服器,那麼就需要用iphash了,iphash的每個請求按通路ip的hash結果配置設定,這樣每個訪客固定通路一個後端伺服器,可以解決session的問題。

upstream test {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
}      

4. fair(第三方)

按後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定。這個配置是為了更快的給使用者響應

upstream backend {
    fair;
    server localhost:8080;
    server localhost:8081;
}      

5. url_hash(第三方)

按通路url的hash結果來配置設定請求,使每個url定向到同一個後端伺服器,後端伺服器為緩存時比較有效。在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,​

​hash_method​

​是使用的hash算法

upstream backend {
    hash $request_uri;
    hash_method crc32;
    server localhost:8080;
    server localhost:8081;
}      

以上5種負載均衡各自适用不同情況下使用,是以可以根據實際情況選擇使用哪種政策模式,不過fair和url_hash需要安裝第三方子產品才能使用。

五、動靜分離

動靜分離是讓動态網站裡的動态網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜态資源的特點将其做緩存操作,這就是網站靜态化處理的核心思路。

upstream web_servers {  
       server localhost:8081;  
       server localhost:8082;  
}

server {
    listen       80;
    server_name  localhost;

    set $doc_root /usr/local/var/www;

    location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
       root $doc_root/img;
    }

    location / {
        proxy_pass http://web_servers;
        # 必須指定Header Host
        proxy_set_header Host $host:$server_port;
    }

    error_page 500 502 503 504  /50x.html;  
    location = /50x.html {  
        root $doc_root;
    }

 }      

六、其他

1.return指令

傳回http狀态碼 和 可選的第二個參數可以是重定向的URL

location /permanently/moved/url {
    return 301 http://www.example.com/moved/here;
}      

2. rewrite指令

重寫URI請求 rewrite,通過使用rewrite指令在請求處理期間多次修改請求URI,該指令具有一個可選參數和兩個必需參數。

第一個(必需)參數是請求URI必須比對的正規表達式。

第二個參數是用于替換比對URI的URI。

可選的第三個參數是可以停止進一步重寫指令的處理或發送重定向(代碼301或302)的标志

location /users/ {
    rewrite ^/users/(.*)$ /show?user=$1 break;
}      

3. error_page指令

error_page 404 /404.html;      

4. 日志

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  /usr/local/etc/nginx/logs/host.access.log  main;

gzip  on;      

5. deny 指令

# 禁止通路某個目錄
location ~* \.(txt|doc)${
    root $doc_root;
    deny all;
}      

6. 内置變量

  • ​$args​

    ​:

    #

    這個變量等于請求行中的參數,同

    $query_string

  • ​$content_length​

    ​:請求頭中的Content-length字段。
  • ​$content_type​

    ​:請求頭中的Content-Type字段。
  • ​$document_root​

    ​:目前請求在root指令中指定的值。
  • ​$host​

    ​:請求主機頭字段,否則為伺服器名稱。
  • ​$http_user_agent​

    ​:用戶端agent資訊
  • ​$http_cookie​

    ​:用戶端cookie資訊
  • ​$limit_rate​

    ​:這個變量可以限制連接配接速率。
  • ​$request_method​

    ​:用戶端請求的動作,通常為GET或POST。
  • ​$remote_addr​

    ​:用戶端的IP位址。
  • ​$remote_port​

    ​:用戶端的端口。
  • ​$remote_user​

    ​:已經經過Auth Basic Module驗證的使用者名。
  • ​$request_filename​

    ​:目前請求的檔案路徑,由root或alias指令與URI請求生成。
  • ​$scheme​

    ​:HTTP方法(如http,https)。
  • ​$server_protocol​

    ​:請求使用的協定,通常是HTTP/1.0或HTTP/1.1。
  • ​$server_addr​

    ​:伺服器位址,在完成一次系統調用後可以确定這個值。
  • ​$server_name​

    ​:伺服器名稱。
  • ​$server_port​

    ​:請求到達伺服器的端口号。
  • ​$request_uri​

    ​:包含請求參數的原始URI,不包含主機名,如:”

    /foo/bar.php?arg=baz

    ”。
  • ​$uri​

    ​:不帶請求參數的目前URI,

    $uri

    不包含主機名,如”

    /foo/bar.html

    ”。
  • ​$document_uri​

    ​:與

    $uri

    相同

繼續閱讀