nginx中除了一些内建变量,自定义变量(通过set指令定义的),还有一类比较特别的变量,我称它们为特殊前缀变量,这类变量多数在
内建变量数组内是找不到的,形式可以分一下几类:
$http_xxx, $sent_http_xxx, $upstream_http_xxx, $cookie_xxx, $arg_xxx。
其中有些常见的http_xxx和sent_http_xxx(其实主要是一些header)在内建变量数组中已经给出,多数偏僻的则没有指明,所以nginx碰到这些变量的时候,就把他们列为"unknown header", 处理这些"unknown header"的方法,则采用统一的handler,因为nginx处理时并不关心内容和细节,从这个角度来说,nginx这种不懂的东西不装懂,做好基本的事情就OK的行为,是值得我们平时为人处世时去借鉴的^_^。
那么这几种变量具体指代什么呢?他们又是如何运作的呢?
$http_xxx,指代那些客户请求过来的header。
$sent_http_xxx,指代将要由nginx发往客户端的header。
$upstream_http_xxx,指代nginx接收到的上游响应header。
$cookie_xxx,用来确定cookie中的特定值。
$arg_xxx,用来取得特定请求参数值
关于他们的实际运作,可以参考ngx_http_variables_init_vars函数,比较简单。
需要提醒一点的就是:标准header名中有‘-’连接线的,要写成‘_’下划线,这是语法上的约定.
比如:要取Accept-Encoding头的内容,可以用$http_Accept_Encoding.
最后来做个总结,看看nginx变量在实际服务时的大致运作流程:
首先在配置解析阶段,nginx完成了延迟执行机制的布置,就像是一个机器组装完毕,现在就等待服务了。类比一下,一个机器的工作,就是一个你给它输入,它吐出输出的过程,类似的,nginx通过函数ngx_http_script_run来完成,它的输入length和value,这两个是nginx设置的延迟执行装置,通过他们的运作,就可以得到一个变量背后的实际值,也就是字符串,字符串自然需要知道它的长度(length)和起始位置(value)了。而我们想要的输出结果,是通过
ngx_http_script_run的第二个参数来返回。总体看就是这些,那么内部呢?
在ngx_http_script_run开始处理中:
for (i = 0; i < cmcf->variables.nelts; i++) {
if (r->variables[i].no_cacheable) {
r->variables[i].valid = 0;
r->variables[i].not_found = 0;
}
}
if (r->variables[i].no_cacheable) {
r->variables[i].valid = 0;
r->variables[i].not_found = 0;
}
}
主要做的工作就是把那些所谓的不能缓存的变量值(no_cacheable),全部置为无效和not fond。这样也就保证了每次要获取这些变量的时候都去重新获取。举个例子,比如$uri,这个变量是用来获得请求uri,而它在整个处理周期中可能会经常变化,例如重写,重定向等操作,所以我们获取它的时候一定要去通过get_handler来获取当前的最新值,所以$uri这个变量在内建变量数组中的初始类型就是no cacheable的。
还有一个需要注意的点就是:e->flushed,一般用的时候我们把它置1,这样我们就希望nginx去通过get_handler来获取最新的变量值。
当有已经缓存的有效变量值是,我们就不去设置它,这样,nginx会先去考察之前已经获得的结果,当不满足使用条件时,在通过get_handler重新取。
差不多了,变量这块就先这样吧,以后发现那些细节在讨论。