cfsky 发表于 2018-11-8 07:58:56

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是设置变量的指令,更多信息请看官方文档,这个不是该文档要讨论的。。。
  #echo "10.0.10.11c.lxm.com" >> /etc/hosts
  # 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
  # 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:                                          
  Starting nginx:                                          
  # curl http://c.lxm.com/test
  foo: hello world    //成功的输出了信息
  #
  到此,可以确定第三方模块添加成功,echo指令也可以使用了。。。。
  测试变量的含义:
  第一组:
  修改配置文件nginx.conf,将test接口改为如下配置:
  location /test {
  echo "args: $args";
  echo "name: $arg_name";
  echo "sex : $arg_sex";
  echo "is_args: $is_args";
  }
  访问测试:
  # curl 'http://c.lxm.com:80/test?name=lxm&sex=man'    //注意:这里的测试url要加上引号,表示加上参数一起是一个完成的url
  args: name=lxm&sex=man
  name: lxm
  sex : man
  is_args: ?
  #
  由上面的测试信息,来解释下面几个变量:
  $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_formattest'$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
  # curl http://c.lxm.com/test/index.html
  welcome to my variables test
  #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
  # 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
  # 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_namea.lxm.com b.lxm.com c.liwei.com;
  #charset koi8-r;
  access_loglogs/host.access.logtestproxy;
  #location / {
  #    root   html;
  #    indexindex.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之后,使用浏览器访问,然后看日志:
  # tail -f host.access.log
  10.0.10.254 backend 8010.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
  测试;
  # 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变量的全部,但是确实是我们常见的变量,因此,有必要去了解一下气含义。
  结束!!!更多技术请看下回分解。。。。
  笨蛋的技术------不怕你不会!!!!

页: [1]
查看完整版本: Nginx系列教程之四:Nginx常用变量汇总及测试