Nginx系列教程之四:Nginx常用變量彙總及測試

Nginx系列教程之:Nginx內置變量的收集及使用
 
前言:
     各位小夥伴,前兩天忙着測試openstack Icehouse,撰寫openstack技術文檔,導致nginx剩下的幾篇博文沒來得及整理,你是不是等着急啦?哈哈,抱歉,今天繼續來聊一聊nginx常用的內
置變量及其相關的使用。

     Nginx的變量在nginx的使用中還是佔了一定的重要性,尤其是在日誌和rewrite中,必須對各種變量的含義有所瞭解,才能組合出適合自己的日誌格式和更高級的rewrite規則。其次瞭解
nginx的變量含義也有助於調試nginx和優化nginx。

     下面列出的變量都是根據nginx官網的變量列表結合平時的使用,整理的一些常用的變量,對於這些變量,有必要了解並記住其含義。。

$args
$arg_PARAMETER
$is_args

$http_HEADER
$http_user_agent
$http_cookie
$sent_http_HEADER
$cookie_COOKIE

$request_body_file
$request_filename
$request_body
$request_method
$request_uri
$content_length
$content_type
$document_root
$document_uri
$remote_addr
$remote_port
$remote_user
$server_protocol
$server_addr
$server_name
$server_port
$binary_remote_addr
$host
$hostname

$scheme
$uri
$limit_rate
$query_string
$realpath_root

$proxy_add_x_forwarded_for
$proxy_host
$proxy_port
$proxy_protocol_addr
$upstream_addr
$upstream_cache_status
$upstream_cookie_
$upstream_http_
$upstream_response_length
$upstream_response_time
$upstream_status 
 
 
測試環境:
OS:CentOS6.4x64
hostname:test1.lxm.com
ip:10.0.10.11
function:nginx前端代理,主要用來測試nginx的各變量

OS:CentOS6.4x64
hostname:test2.lxm.com
ip:10.0.10.12
function:LNMP後端服務器,用來提供一個簡單的測試頁面而已(主要是爲了測試前端nginx反向代理到後端的變量值)

    爲了展示測試的效果,此次測試需要安裝一個nginx的第三方模塊:echo-nginx-module-0.55.tar.gz. 藉助於該模塊中的一個指令:echo 可以將個變量的值輸出到終端上,給各位一個只管的感受。避免盲目的文字介紹,搞的頭暈腦脹,也省的自己記錯了。。哈哈。。。

 

安裝echo-nginx-module-0.55.tar.gz:
在我的測試環境中,已經安裝好了nginx,此時要再安裝第三方模塊,則要使用下面的方法:
#cd /root/soft
#tar -zxvf nginx-1.6.1.tar.gz
#cd nginx-1.6.1
#./configure --prefix=/usr/local/nginx/ --with-pcre --with-http_ssl_module --with-openssl=/root/soft/openssl-1.0.1i --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --http-client-body-temp-path=/usr/local/nginx/client_body_temp/ --http-proxy-temp-path=/usr/local/nginx/proxy_temp/ --http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp/ --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp/ --http-scgi-temp-path=/usr/local/nginx/scgi_temp/ --add-module=../echo-nginx-module-0.55
#make
#/usr/local/nginx/sbin/nginx -s stop
#cp -p objs/nginx /usr/local/nginx/sbin/nginx  //覆蓋掉原先的nginx執行文件

說明:
1.--add-module
 該選項是nginx的一個編譯參數,用來添加額外的第三方模塊。因此可知,對任何第三方模塊都是使用該方法來添加進nginx中
2.以上的安裝可見沒有make install這一步,這是因爲我已經安裝了nginx,我只需要更新我的可執行程序,而其他的文件我不需要更新,這也是nginx升級的原理。如果沒有安裝過nginx,則需
要make install這一步

 

附:ngx_echo 模塊的下載地址

https://github.com/openresty/echo-nginx-module/releases

 


測試echo指令是否可用:
#vim /usr/local/nginx/conf/nginx.conf
修改配置文件,添加一個server段做測試,配置如下:
 server {
        listen 80;
        server_name c.lxm.com;
        access_log /data/logs/access.log main;
        location / {
                root /data;
                index index.html index.htm;
        }
        location /test {
            set $foo "hello world";
            echo "foo: $foo";
        }
 由上面的信息可知,這裏我使用了一個/test接口來測試echo指令是否可用。

注:有的人可能會問,什麼叫接口啊?說白了接口就是一個訪問路徑,訪問入口而已,通過這個入口可以進行交互的作用。。其次這裏的set是設置變量的指令,更多信息請看官方文檔,這個不是該文檔要討論的。。。

[root@test1 conf]#echo "10.0.10.11  c.lxm.com" >> /etc/hosts
[root@test1 conf]# service nginx configtest
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@test1 conf]# service nginx restart
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]
[root@test1 conf]# curl
http://c.lxm.com/test
foo: hello world    //成功的輸出了信息
[root@test1 conf]#
  
到此,可以確定第三方模塊添加成功,echo指令也可以使用了。。。。


測試變量的含義:
第一組:
修改配置文件nginx.conf,將test接口改爲如下配置:
  location /test {
            echo "args: $args";
            echo "name: $arg_name";
            echo "sex : $arg_sex";
            echo "is_args: $is_args";
        }
  
訪問測試:
[root@test1 conf]# curl 'http://c.lxm.com:80/test?name=lxm&sex=man'    //注意:這裏的測試url要加上引號,表示加上參數一起是一個完成的url
args: name=lxm&sex=man
name: lxm
sex : man
is_args: ?
[root@test1 conf]#

由上面的測試信息,來解釋下面幾個變量:
$args :該變量用來獲取url後面的所有參數 ,?表示參數的起始處
$arg_PARAMETER :這是參數的一個匹配模式,PARAMETER爲具體的參數名,$arg_PARAMETER就表示獲取具體的參數值,例如上面的$arg_name就是獲取url中name的值
$is_args  :判斷url是否帶參數,如果帶,則返回一個?,否則返回一個空字符串

 

第二組:
$http_HEADER    //使用該方式來獲取http請求頭部中的值,HEADER是一個匹配模式,匹配請求頭部中key:value中的可以,返回的是value
$sent_http_HEADER  //使用該方式來獲取http響應頭部中的值,HEADER是一個匹配模式,匹配響應頭部中key:value中的可以,返回的是value

由於這個涉及到http請求流的問題,這裏採用日誌的形式展示效果,如果用echo來返回,有點東西測試不出來。。

新建一日誌格式:
 log_format  test  '$http_user_agent $sent_http_content_type $sent_http_content_length';

修改test接口的server部分:
   server {
        listen 80;
        server_name c.lxm.com;
        access_log /data/logs/access.log test;
        location / {
                root html;
                index index.html index.htm;

        }
        location /test {
                root html;
                index   index.html index.htm;
        }

    }
 
#service nginx configtest
#service nginx restart

[root@test1 conf]# curl http://c.lxm.com/test/index.html
<h1>welcome to my variables test</h1>
[root@test1 conf]#curl -I
http://c.lxm.com/test/index.html  //獲取的是響應頭中的信息
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 01 Sep 2014 06:56:18 GMT
Content-Type: text/html
Content-Length: 38
Last-Modified: Mon, 01 Sep 2014 06:43:54 GMT
Connection: keep-alive
ETag: "540415aa-26"
X-Cache-TEST:  -
Accept-Ranges: bytes
[root@test1 logs]# tail -f access.log
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0 text/html 38
curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2 text/html 38
 
由上面的訪問測試和日誌顯示,變量成功獲取到了值。。
$http_user_agent: //獲取的是客戶端訪問代理的類型,請求頭中的信息
$sent_http_content_type : //獲取的是http響應頭中content_type的值
$sent_http_content_length: //獲取的是http響應頭重的content_length的值

注意:在變量中的字符串一律是小寫,雖然在請求頭和響應頭中的字符串可能有大寫,但是nginx會一律將其轉換爲小寫之後進行匹配。。。

此外,要想知道http請求頭和響應頭中都有些什麼內容,建議使用火狐瀏覽器的F12調試功能中的網絡功能,來獲取請求頭和響應頭的信息。。。。

還要扒拉一句的是:雖然這兩個變量可以獲取頭部中的信息值,但是經過我的測試,並不是對所有的都有效,起碼在響應頭中的date和server,本人沒測試成功,總是返回空值。或許你該注意。。
 
 

第三組:
配置文件如下:
 server {
        listen 80;
        server_name c.lxm.com;
        access_log /data/logs/access.log test;
        location / {
                root html;
                index index.html index.htm;

        }
        location /test {
        proxy_pass
http://backend;
        proxy_redirect off;
        echo "uri: $uri";
        echo "request_uri: $request_uri";
        echo "request_method: $request_method";
        echo "request_filename: $request_filename";
        echo "content_length: $content_length";
        echo "content_type: $content_type";
        echo "document_root: $document_root";
        echo "document_uri: $document_uri";
        echo "server_addr: $server_addr";
        echo "server_name: $server_name";
        echo "server_port: $server_port";
        echo "server_protocol: $server_protocol";
        echo "host: $host";
        echo "hostname: $hostname";
        echo "remote_addr: $remote_addr";
        echo "remote_user: $remote_user";
        echo "remote_port: $remote_port";
  }
 }
 
#service nginx configtest
#service nginx restart

[root@test1 conf]# curl 'http://c.lxm.com:80/test/index.html?name=lxm&sex=man'
uri: /test/index.html
request_uri: /test/index.html?name=lxm&sex=man
request_method: GET
request_filename: /usr/local/nginx//html/test/index.html
content_length:
content_type:
document_root: /usr/local/nginx//html
document_uri: /test/index.html
server_addr: 10.0.10.11
server_name: c.lxm.com
server_port: 80
server_protocol: HTTP/1.1
host: c.lxm.com
hostname: test1.lxm.com
remote_addr: 10.0.10.11
remote_user:
remote_port: 57292

根據上面的輸出信息,來解釋一下下面的變量:
$request_filename  //該變量獲取的是請求的文件在linux服務器上的完整的絕對路徑
$request_method  //該表示獲取的是http請求的方法
$request_uri  //該變量表示的原始請求的uri,包括參數。所謂原始請求就是即使在內部做了重定向之後也不會變化
$uri  //獲取的是當前請求的uri,不包括參數
$content_length  //獲取的是http請求頭中Content-Length的值,不過這裏似乎沒顯示,抱歉這裏的測試頁面中沒有該字段
$content_type   //獲取的是http請求頭中的Content-Type字段,不過這裏也沒顯示。。。
$document_root   //獲取的是請求url的文件所在的目錄路徑
$document_uri   //當前請求的uri,從上面的信息來看,和uri的效果是一樣的
$remote_addr  //獲取的是客戶端的ip地址,這裏爲什麼是10.0.10.11呢,因爲我是在本機上用curl測試的,即使客戶端也是服務器
$remote_port  //獲取客戶端的訪問端口,這個端口是隨機的
$remote_user  //獲取客戶端的認證用戶信息,這裏因爲沒有用認證,所謂顯示爲空
$server_protocol  //表示服務器端想客戶端發送響應的協議
$server_addr  //服務器的地址
$server_name  //客戶端訪問服務端的域名,即url中的域名
$server_port //服務器端做出響應的端口號
$binary_remote_addr  //顯示二進制的客戶端地址
$host  //和server_name一樣,表示的是域名
$hostname  //表示服務器端的主機名

第四組:
 對於這一組使用日誌的形式來展示。。
 
修改配置文件nginx.conf:
log_format   testproxy  '$proxy_add_x_forwarded_for $proxy_host $proxy_port $proxy_protocol_addr $upstream_addr $upstream_cache_status $upstream_response_length $upstream_response_time $upstream_status';

 server {
       listen      80;
        server_name  a.lxm.com b.lxm.com c.liwei.com;

        #charset koi8-r;

        access_log  logs/host.access.log  testproxy;

        #location / {
        #    root   html;
        #    index  index.html index.htm;
        #    auth_basic "relam authentication";
        #    auth_basic_user_file /usr/local/nginx/htpasswd;
        #}
        location / {
                root html;
                proxy_redirect off;
                proxy_pass  
http://backend;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
                proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header;
                proxy_cache cache_one;
                proxy_cache_valid 200 302 1h;
                proxy_cache_valid 301 1d;
                proxy_cache_valid any 1m;
                expires 30d;
        }

}

注意:上面的內容是nginx配置文件的一個片段,只是跟我們的測試內容相關而已
  
#service nginx configtest
#service nginx restart

啓動nginx之後,使用瀏覽器訪問,然後看日誌:
[root@test1 logs]# tail -f host.access.log
10.0.10.254 backend 80  10.0.10.12:80 MISS 91 0.004 200
10.0.10.254 backend 80  - HIT - - -

根據上面的信息,來解釋一下下面的變量:
$proxy_add_x_forwarded_for :獲取的是客戶端的真實ip地址
$proxy_host   :該變量獲取的是upstream的上游代理名稱,例如upstream backend
$proxy_port   //該變量表示的是要代理到的端口
$proxy_protocol_addr  //代理頭部中客戶端的ip地址,或者是一個空的字符串
$upstream_addr  //代理到上游的服務器地址信息
$upstream_cache_status    //proxy的緩存狀態,例如這裏第一次訪問爲MISS,第二次訪問時爲HIT
$upstream_response_length  //上游服務器響應報文的長度
$upstream_response_time  //上游服務器響應的時間
$upstream_status  //上游服務器響應的狀態碼

 

第五組:
配置文件nginx.conf:
 server {
        listen 80;
        server_name c.lxm.com;
        access_log /data/logs/access.log test;
        location / {
                root html;
                index index.html index.htm;

        }
        location /test {
  echo "scheme: $scheme";
        echo "limit_rate: $limit_rate";
        echo "query_string: $query_string";
        echo "realpath_root: $realpath_root";
        }

    }

#service nginx configtest
#service nginx restart

測試;
[root@test1 conf]# curl 'http://c.lxm.com:80/test/index.html?name=lxm&sex=man'
scheme: http
limit_rate: 0
query_string: name=lxm&sex=man
realpath_root: /usr/local/nginx/html

根據上面的信息,解釋下面幾個變量;
$scheme  //表示的是使用http的訪問協議 http or https
$limit_rate  //表示當前連接的限速是多少,0表示無限制
$query_string  //表示的是查詢字符串,也就是url中的參數,和$args一樣
$realpath_root  //表示的是請求頁面的真實所在目錄的路徑  和$document_root是一樣的


到此,關於nginx的常用變量就聊到這個地方,這並不是nginx變量的全部,但是確實是我們常見的變量,因此,有必要去了解一下氣含義。

結束!!!更多技術請看下回分解。。。。
 
 笨蛋的技術------不怕你不會!!!!

 

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