Nginx Record


簡介

nginx是開發中常用的web server,又可以做反向代理,另外k8s中的ingress默認使用的也是nginx,所以有必要深入了解下nginx的相關知識,及一些必要的原理知識。

常用指令

location

location [=|~|~*|^~|@] pattern { ... }
  • =代表路徑完全匹配
  • ~區分大小寫的正則匹配
server {
    server_name web.com;
    location ~ ^/abcd$ {
    […]
    }
}

^/abcd\(這個正則表達式表示字符串必須以/開始,以\)結束,中間必須是abcd

http://web.com/abcd匹配(完全匹配)
http://web.com/ABCD不匹配,大小寫敏感
http://web.com/abcd?param1&param2匹配
http://web.com/abcd/不匹配,不能匹配正則表達式
http://web.com/abcde不匹配,不能匹配正則表達式
  • ~* 不區分大小寫的正則匹配
  • ^~ 普通字符匹配,不是正則匹配。如果該選項匹配,只匹配該選項,不匹配別的選項,一般用來匹配目錄
  • @ 定義一個命名的location,使用在內部定向時,例如error_page,try_files

查找的順序及優先級

當有多條 location 規則時,nginx 有一套比較復雜的規則,優先級如下:

1). =前綴的指令嚴格匹配這個查詢。如果找到,停止搜索。

2). 所有剩下的常規字符串,最長的匹配。如果這個匹配使用^~前綴,搜索停止。

3). 正則表達式,在配置文件中定義的順序。

4). 如果第3條規則產生匹配的話,結果被使用。否則,如同從第2條規則被使用。

順序or優先級: (location =) > (location ^~ 路徑 最長匹配的意思) > (location ,* 正則順序) > (location 部分起始路徑) > (/)

rewrite模塊

break

break
Context: server, location, if

停止執行 ngx_http_rewrite_module 的指令集,但是其他模塊指令是不受影響的

官方:

last
   stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;

break
   stops processing the current set of ngx_http_rewrite_module directives;

last: 停止當前這個請求,並根據rewrite匹配的規則重新發起一個請求。新請求又從第一階段開始執行…
break:相對last,break並不會重新發起一個請求,只是跳過當前的rewrite階段,並執行本請求后續的執行階段…
實例

server {
    listen 80 default_server;
    server_name dcshi.com;
    root www;

    location /break/ {
        rewrite ^/break/(.*) /test/$1 break;
        echo "break page";
    } 

    location /last/ {
         rewrite ^/last/(.*) /test/$1 last;
         echo "last page";
    }    

    location /test/ {
       echo "test page";
    }
}

if

Context: server, location

依據指定的條件決定是否執行 if 塊語句中的內容

if 中的幾種 判斷條件

  • 一個變量名,如果變量 $variable 的值為空字符串或者字符串"0",則為false
  • 變量與一個字符串的比較 相等為(=) 不相等為(!=) 注意此處不要把相等當做賦值語句啊
  • 變量與一個正則表達式的模式匹配 操作符可以是(~ 區分大小寫的正則匹配, ~不區分大小寫的正則匹配, !~ !~,前面兩者的非)
  • 檢測文件是否存在 使用 -f(存在) 和 !-f(不存在)
  • 檢測路徑是否存在 使用 -d(存在) 和 !-d(不存在) 后面判斷可以是字符串也可是變量
  • 檢測文件、路徑、或者鏈接文件是否存在 使用 -e(存在) 和 !-e(不存在) 后面判斷可以是字符串也可是變量
  • 檢測文件是否為可執行文件 使用 -x(可執行) 和 !-x(不可執行) 后面判斷可以是字符串也可是變量
set $variable "0"; 
if ($variable) {
    # 不會執行,因為 "0" 為 false
    break;            
}

# 使用變量與正則表達式匹配 沒有問題
if ( $http_host ~ "^star\.igrow\.cn$" ) {
    break;            
}

# 字符串與正則表達式匹配 報錯
if ( "star" ~ "^star\.igrow\.cn$" ) {
    break;            
}
# 檢查文件類的 字符串與變量均可
if ( !-f "/data.log" ) {
    break;            
}

if ( !-f $filename ) {
    break;            
}

if中&&的實現,參考:

        // 匹配click路徑且參數中帶有name=walkingsun 重定向到click-ios路徑
        set $flag 0;
        if ( $uri = /click) {
          set $flag 1;
        }
        if ( $args ~ name=walkingsun ) {
          set $flag 1$flag;
        }
        if ( $flag = 11 ) {
          rewrite ^/(.*) $uri-ios break;
        }

return

Context: server, location, if

return code [text];
return code URL;
return URL;

停止處理並將指定的code碼返回給客戶端。 非標准code碼 444 關閉連接而不發送響應報頭

有一種特殊情況,就是重定向的url可以指定為此服務器本地的urI,這樣的話,nginx會依據請求的協議$scheme, server_name_in_redirect 和 port_in_redirect自動生成完整的 url (此處要說明的是server_name_in_redirect 和port_in_redirect 指令是表示是否將server塊中的 server_name 和 listen 的端口 作為redirect用 )

變量

定義變量

set $foo hello;

內置變量

  • $request_method 請求方式
  • $args query params
  • $request_uri $request_uri 則用來獲取請求最原始的 URI (未經解碼,並且包含請求參數)
  • $uri 獲取當前請求的 URI(經過解碼,並且不含請求參數)
  • $arg_xxx 特別常用的內建變量其實並不是單獨一個變量,而是有無限多變種的一群變量,即名字以 arg_ 開頭的所有變量,我們估且稱之為 $arg_XXX 變量群。一個例子是 $arg_name,這個變量的值是當前請求中名為 name 的參數的值,而且還是未解碼的原始形式的值。
location /test-arg {
    echo "name: $arg_name";
    echo "class: $arg_class";
}

$arg_name 不僅可以匹配 name 參數,也可以匹配 NAME 參數,抑或是 Name,Nginx 會在匹配參數名之前,自動把原始請求中的參數名調整為全部小寫的形式

  • $cookie_XXX 取 cookie 值變量群
  • $http_XXX

全局變量

arg_PARAMETER #這個變量包含GET請求中,如果有變量PARAMETER時的值。
args #這個變量等於請求行中(GET請求)的參數,如:foo=123&bar=blahblah;
binary_remote_addr #二進制的客戶地址。
body_bytes_sent #響應時送出的body字節數數量。即使連接中斷,這個數據也是精確的。
content_length #請求頭中的Content-length字段。
content_type #請求頭中的Content-Type字段。
cookie_COOKIE #cookie COOKIE變量的值
document_root #當前請求在root指令中指定的值。
document_uri #與uri相同。
host #請求主機頭字段,否則為服務器名稱。
hostname #Set to themachine’s hostname as returned by gethostname
http_HEADER
is_args #如果有args參數,這個變量等於”?”,否則等於”",空值。

# nginx取請求中header的XXX的值
http_user_agent #客戶端agent信息
http_cookie #客戶端cookie信息
http_origin #origin,而一般跨域請求都會將請求的來源放在origin中(瀏覽器會往跨域請求的header上面加origin這個header)

limit_rate #這個變量可以限制連接速率。
query_string #與args相同。
request_body_file #客戶端請求主體信息的臨時文件名。
request_method #客戶端請求的動作,通常為GET或POST。
remote_addr #客戶端的IP地址。
remote_port #客戶端的端口。
remote_user #已經經過Auth Basic Module驗證的用戶名。
request_completion #如果請求結束,設置為OK. 當請求未結束或如果該請求不是請求鏈串的最后一個時,為空(Empty)。
request_method #GET或POST
request_filename #當前請求的文件路徑,由root或alias指令與URI請求生成。
request_uri #包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。不能修改。
scheme #HTTP方法(如http,https)。
server_protocol #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
server_addr #服務器地址,在完成一次系統調用后可以確定這個值。
server_name #服務器名稱。
server_port #請求到達服務器的端口號

Module

ngx_http_mirror_module

implements mirroring of an original request by creating background mirror subrequests. Responses to mirror subrequests are ignored.
通過創建后台鏡像子請求實現原始請求的鏡像。對鏡像子請求的響應將被忽略;
場景:可以做流量復制,不關心響應。作為機房遷移上雲的過渡挺合適的,或者說是作為復制請求測試。

location / {
    mirror /mirror;
    proxy_pass http://backend;
}

location = /mirror {
    internal;
    proxy_pass http://test_backend$request_uri;
}

參考:http://nginx.org/en/docs/http/ngx_http_mirror_module.html

參考

https://segmentfault.com/a/1190000008102599


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM