1. 程式人生 > >nginx變數學習初步-讀章亦春的部落格做個筆記

nginx變數學習初步-讀章亦春的部落格做個筆記

nginx學習筆記

set

location /hi{
    set $a "hi";
    return 200  "hello";
}
  • 這裡的set $a會建立一個變數,並賦值為hi,注意的是,nignx啟動時,變數已建立,但是在具體執行到這裡後變數值才被賦值,也就是說,建立和賦值是分開的。
  • nignx變數名的可見範圍是整個配置,但是不同的請求之間是彼此隔離的,變數的宣告週期與請求相關,與location無關。(這裡可以聯想變成語言中,全域性變數可以在各個函式體中被引用,但是如果分開執行兩次,彼此是隔離的)

內建變數

nginx有很多內建的變數群,需要注意,在 $arg_xxx

中,可以獲取名為xxx的請求引數,並且自動將所有get的引數轉為小寫之後進行匹配。

location /hi{
   add_header oriuri $uri;
    add_header requri $request_uri;
    add_header post $arg_post;
    return 301 "www.baidu.com";
    }
curl hongjian.cn/hi?post=helloworld -v
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Sun, 23
Apr 2017 10:10:12 GMT < Content-Type: text/html < Content-Length: 178 < Connection: keep-alive < Location: www.baidu.com < oriuri: /hi < requri: /hi?post=helloworld < post: helloworld

類似 argXXXcookiecookie_XXX 變數群,用來取請求頭的 httpXXXsent_http_XXX 變數群。這裡就不一一介紹了,感興趣可以參考

ngx_http_core 模組的官方文件。

大部分內建變數都只是可讀的,如果去賦值,會在啟動nginx時報錯

取處理與存處理

不是所有的 Nginx 變數都擁有存放值的容器。擁有值容器的變數在 Nginx 核心中被稱為“被索引的”(indexed);反之,則被稱為“未索引的”(non-indexed)。$arg_xxx就是未索引的變數。

在我們讀取類似 $arg_xxx 內建變數群時,nginx會執行相應的讀處理程式掃描URL的引數串去獲取這個變數的值,$cookie_xxx也是這樣的.

nginx值容器快取

http{
    map $arg_method $ret {
        GET 1;
        POST 2;
        PUT 3;
        DELETE 4;
        default 5;
    }
    server {
        location /hi {
        #set $arg_method get;
        return 200 "ret:$ret";
    }
}

這裡我們使用了一個nginx中的map對映規則。這個map只能解除安裝http模組中,所以也就是全域性的了。這裡我們看一下請求情況

curl hongjian.cn/hi\?method=post
ret:2

curl hongjian.cn/hi\?method=POST
ret:2

這裡我們可以看到,請求引數中的method,會按照map中的規則,對映為對應值,並且nginx會將引數轉成小寫後進行比較。

注意到上面的set語句是被註釋掉的,這裡我們將註釋開啟後,再次訪問。

curl hongjian.cn/hi\?method=POST
ret:1

返回值變成了1,那這裡就印證了一個事實,在取值(取ret)時,才會進行計算,這裡我們稱這種現象為惰性計算。這裡還看不到和快取有什麼關係,我們再做一個小調整。

http{
    map $arg_method $ret {
        GET 1;
        POST 2;
        PUT 3;
        DELETE 4;
        default 5;
    }
    server {
        location /hi {
        set $ret1 $ret;
        set $arg_method default;
        set $ret2 $ret;
        return 200 "ret1:$ret, ret2:$ret2";
    }
}

訪問一下,檢視請求結果

curl hongjian.cn/hi\?method=post
ret1:2, ret2:2

ret2並沒有因為我們將method變數設定為default而變化,這是為什麼呢?原來,nginx可以為建立的變數選擇值容器來作為快取,ngx_map這種結構被認定計算耗費大,所以會進行快取,因為惰性計算,只有在第一次執行對ret的取程式時,才會計算ret的map結果,並將這個值作為快取,所以之後我們就算修改了method的值,下一條語句執行取程式時,還會返回上次快取的結果。快取值容器的宣告週期是和請求相關聯的

所以這種全域性性的map結構,只有一個請求的第一次取程式執行時才會被計算一次,之後執行取程式時,會使用快取結果。

主動計算也很常見

比如set賦值操作就會進行即時計算並將結果賦值給變數。

關於父子請求

這裡說的子請求並不是真正意義上的一個子HTTP請求,而是藉助第三方模組,比如ngx_location發起的一個C語言的呼叫而已,父子請求間對於變數有共享也有非共享的,遇到之後再作具體查詢和分析。